{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Configuration for Colab"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import sys\n",
    "IN_COLAB = \"google.colab\" in sys.modules\n",
    "\n",
    "if IN_COLAB:\n",
    "    !apt install python-opengl\n",
    "    !apt install ffmpeg\n",
    "    !apt install xvfb\n",
    "    !pip install pyvirtualdisplay\n",
    "    from pyvirtualdisplay import Display\n",
    "    \n",
    "    # Start virtual display\n",
    "    dis = Display(visible=0, size=(600, 400))\n",
    "    dis.start()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 04. TD3\n",
    "\n",
    "[Fujimoto, Scott, Herke van Hoof, and David Meger. \"Addressing function approximation error in actor-critic methods.\" arXiv preprint arXiv:1802.09477 2018.](https://arxiv.org/pdf/1802.09477.pdf)\n",
    "\n",
    "In value-based reinforcement learning methods, function approximation errors are known to lead to overestimated value estimates and suboptimal policies. However, similar issues with actor-critic methods in continuous control domains have been largely left untouched (See paper for detailed description). To solve this problem, this paper proposes *a clipped Double Q-learning*. In addtion, this paper contains a number of components that address variance reduction.\n",
    "\n",
    "The author's modifications are applied to actor-critic method for continuous control, Deep Deterministic Policy Gradient algorithm ([DDPG](https://arxiv.org/pdf/1509.02971.pdf)), to form the *Twin Delayed Deep Deterministic policy gradient algorithm (TD3)*.\n",
    "\n",
    "### DDPG\n",
    "For learning in high-dimentional and continous action spaces, the authors of DDPG combine the actor-critic approach with insights from the success of DQN. Deep DPG(DDPG) is based on the deterministic policy gradient(DPG) algorithm ([Silver et al., 2014](http://proceedings.mlr.press/v32/silver14.pdf)). Please see *03.DDPG.ipynb* for detailed description of DDPG.\n",
    "\n",
    "### Double Q-learning\n",
    "In Double DQN ([Van Hasselt et al., 2016](https://arxiv.org/pdf/1509.06461.pdf)), the authors propose using the target network as one of the value estimates, and obtain a policy by greedy maximization of the current value network rather than the target network. In an actor-critic setting, an analogous update uses the current policy rather than the target policy in the learning target. However, with the slow-changing policy in actor-critic, the current and target networks were too similar to make an independent estimation, and offered little improvement. Instead, the original Double Q-learning formulation can be used, with a pair of actors $(\\pi_{\\phi_1}, \\pi_{\\phi_2})$ and critics $(Q_{\\theta_1}, Q_{\\theta_2})$, where $\\pi_{\\phi_1}$ is optimized with respect to $Q_{\\theta_1}$ and $\\pi_{\\phi_2}$ with respect to $Q_{\\theta_2}$:\n",
    "\n",
    "$$\n",
    "y_1 = r + \\gamma Q_{\\theta'_2} (s' , \\pi_{\\phi_1}(s')) \\\\\n",
    "y_2 = r + \\gamma Q_{\\theta'_1} (s' , \\pi_{\\phi_2}(s'))\n",
    "$$\n",
    "\n",
    "### A clipped Double Q-learning\n",
    "The critics are not entirely independent, due to the use of the opposite critic in the learning targets, as well as the same replay buffer. As a result, for some states we will have $Q_{\\theta'_2}(s, \\pi_{\\phi_1}) > Q_{\\theta'_1}(s, \\pi_{\\phi_1})$. This is problematic because $Q_{\\theta'_1}(s, \\pi_{\\phi_1})$ will generally overestimate the true value, and in certain areas of the state space the overestimation will be further exaggerated. To address this problem, the authors propose to take the minimum between the two estimates:\n",
    "\n",
    "$$\n",
    "y_1 = r + \\gamma \\underset{i=1,2}{\\min} Q_{\\theta'_i} (s' , \\pi_{\\phi_1}(s'))\n",
    "$$\n",
    "\n",
    "### Delayed Policy Updates\n",
    "If policy updates on high-error states cause different behavior, then the policy network should be updated at a lower frequency than the value network, to first minimize error before introducing a policy update. The authors propose delaying policy updates until the value error is as small as possible.\n",
    "\n",
    "### Target Policy Smoothing Regularization\n",
    "When updating the critic, a learning target using a deterministic policy is highly susceptible to in accuracies induced by function approximation error, increasing the variance of the target. This induced variance can be reduced through regularization. The authors propose that fitting the value of a small area around the target action\n",
    "\n",
    "$$\n",
    "y = r + E_\\epsilon [Q_{\\theta'}(s', \\pi_{\\phi '}(s') + \\epsilon],\n",
    "$$\n",
    "\n",
    "would have the benefit of smoothing the value estimate by bootstrapping off of similar state-action value estimates. In practice, this makes below:\n",
    "\n",
    "$$\n",
    "y = r + \\gamma Q_{\\theta '}(s', \\pi_{\\phi '}(s') + \\epsilon), \\\\\n",
    "\\epsilon \\sim \\text{clip} (\\mathcal(N)(0, \\sigma), -c, c),\n",
    "$$\n",
    "\n",
    "where the added noise is clipped to keep the target close tothe original action."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## import module"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "import os\n",
    "import random\n",
    "from typing import Dict, List, Tuple\n",
    "\n",
    "import gym\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "from IPython.display import clear_output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Set random seed"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "if torch.backends.cudnn.enabled:\n",
    "    torch.backends.cudnn.benchmark = False\n",
    "    torch.backends.cudnn.deterministic = True\n",
    "\n",
    "seed = 777\n",
    "torch.manual_seed(seed)\n",
    "np.random.seed(seed)\n",
    "random.seed(seed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Replay buffer\n",
    "Typically, people implement replay buffers with one of the following three data structures:\n",
    "\n",
    "- collections.deque\n",
    "- list\n",
    "- numpy.ndarray\n",
    "\n",
    "**deque** is very easy to handle once you initialize its maximum length (e.g. deque(maxlen=buffer_size)). However, the indexing operation of deque gets terribly slow as it grows up because it is [internally doubly linked list](https://wiki.python.org/moin/TimeComplexity#collections.deque). On the other hands, **list** is an array, so it is relatively faster than deque when you sample batches at every step. Its amortized cost of Get item is [O(1)](https://wiki.python.org/moin/TimeComplexity#list).\n",
    "\n",
    "Last but not least, let's see **numpy.ndarray**. numpy.ndarray is even faster than list due to the fact that it is [a homogeneous array of fixed-size items](https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html#numpy.ndarray), so you can get the benefits of [locality of reference](https://en.wikipedia.org/wiki/Locality_of_reference), . Whereas list is an array of pointers to objects, even when all of them are of the same type.\n",
    "\n",
    "Here, we are going to implement a replay buffer using numpy.ndarray.\n",
    "\n",
    "Reference: \n",
    "- [OpenAI spinning-up](https://github.com/openai/spinningup/blob/master/spinup/algos/sac/sac.py#L10)\n",
    "- [rainbow-is-all-you-need](https://render.githubusercontent.com/view/ipynb?commit=032d11277cf2436853478a69ca5a4aba03202598&enc_url=68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f437572742d5061726b2f7261696e626f772d69732d616c6c2d796f752d6e6565642f303332643131323737636632343336383533343738613639636135613461626130333230323539382f30312e64716e2e6970796e62&nwo=Curt-Park%2Frainbow-is-all-you-need&path=01.dqn.ipynb&repository_id=191133946&repository_type=Repository#Replay-buffer)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ReplayBuffer:\n",
    "    \"\"\"A simple numpy replay buffer.\"\"\"\n",
    "\n",
    "    def __init__(self, obs_dim: int, size: int, batch_size: int = 32):\n",
    "        self.obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n",
    "        self.next_obs_buf = np.zeros([size, obs_dim], dtype=np.float32)\n",
    "        self.acts_buf = np.zeros([size], dtype=np.float32)\n",
    "        self.rews_buf = np.zeros([size], dtype=np.float32)\n",
    "        self.done_buf = np.zeros(size, dtype=np.float32)\n",
    "        self.max_size, self.batch_size = size, batch_size\n",
    "        self.ptr, self.size, = 0, 0\n",
    "\n",
    "    def store(\n",
    "        self,\n",
    "        obs: np.ndarray,\n",
    "        act: np.ndarray,\n",
    "        rew: float,\n",
    "        next_obs: np.ndarray,\n",
    "        done: bool,\n",
    "    ):\n",
    "        self.obs_buf[self.ptr] = obs\n",
    "        self.next_obs_buf[self.ptr] = next_obs\n",
    "        self.acts_buf[self.ptr] = act\n",
    "        self.rews_buf[self.ptr] = rew\n",
    "        self.done_buf[self.ptr] = done\n",
    "        self.ptr = (self.ptr + 1) % self.max_size\n",
    "        self.size = min(self.size + 1, self.max_size)\n",
    "\n",
    "    def sample_batch(self) -> Dict[str, np.ndarray]:\n",
    "        idxs = np.random.choice(self.size, size=self.batch_size, replace=False)\n",
    "        return dict(\n",
    "            obs=self.obs_buf[idxs],\n",
    "            next_obs=self.next_obs_buf[idxs],\n",
    "            acts=self.acts_buf[idxs],\n",
    "            rews=self.rews_buf[idxs],\n",
    "            done=self.done_buf[idxs],\n",
    "        )\n",
    "\n",
    "    def __len__(self) -> int:\n",
    "        return self.size"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Gaussian Noise\n",
    "Because the DDPG and the TD3 policy is deterministic, it's not enough to explore a wide variety of actions. In order to facilitate more exploration. TD3 adds Gaussian noise to each action, while DDPG uses Ornstein-Uhlenbeck noise. The TD3 paper states Ornstein-Uhlenbeck noise offered no performance benefits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "class GaussianNoise:\n",
    "    \"\"\"Gaussian Noise.\n",
    "    Taken from https://github.com/vitchyr/rlkit\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(\n",
    "        self,\n",
    "        action_dim: int,\n",
    "        min_sigma: float = 1.0,\n",
    "        max_sigma: float = 1.0,\n",
    "        decay_period: int = 1000000,\n",
    "    ):\n",
    "        \"\"\"Initialize.\"\"\"\n",
    "        self.action_dim = action_dim\n",
    "        self.max_sigma = max_sigma\n",
    "        self.min_sigma = min_sigma\n",
    "        self.decay_period = decay_period\n",
    "\n",
    "    def sample(self, t: int = 0) -> float:\n",
    "        \"\"\"Get an action with gaussian noise.\"\"\"\n",
    "        sigma = self.max_sigma - (self.max_sigma - self.min_sigma) * min(\n",
    "            1.0, t / self.decay_period\n",
    "        )\n",
    "        return np.random.normal(0, sigma, size=self.action_dim)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network\n",
    "We are going to use two separated networks for actor and critic. The actor network has three fully connected layers and three non-linearity functions, *ReLU* for hidden layers and *tanh* for the output layer. On the other hand, the critic network has three fully connected layers, but it used two activation functions for hidden layers *ReLU*. Plus, its input sizes of critic network are sum of state sizes and action sizes. One thing to note is that we initialize the final layer's weights and biases so that they are *uniformly distributed.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Actor(nn.Module):\n",
    "    def __init__(self, in_dim: int, out_dim: int, init_w: float = 3e-3):\n",
    "        \"\"\"Initialize.\"\"\"\n",
    "        super(Actor, self).__init__()\n",
    "\n",
    "        self.hidden1 = nn.Linear(in_dim, 128)\n",
    "        self.hidden2 = nn.Linear(128, 128)\n",
    "        self.out = nn.Linear(128, out_dim)\n",
    "\n",
    "        self.out.weight.data.uniform_(-init_w, init_w)\n",
    "        self.out.bias.data.uniform_(-init_w, init_w)\n",
    "\n",
    "    def forward(self, state: torch.Tensor) -> torch.Tensor:\n",
    "        \"\"\"Forward method implementation.\"\"\"\n",
    "        x = F.relu(self.hidden1(state))\n",
    "        x = F.relu(self.hidden2(x))\n",
    "        action = self.out(x).tanh()\n",
    "\n",
    "        return action\n",
    "\n",
    "\n",
    "class Critic(nn.Module):\n",
    "    def __init__(self, in_dim: int, init_w: float = 3e-3):\n",
    "        \"\"\"Initialize.\"\"\"\n",
    "        super(Critic, self).__init__()\n",
    "\n",
    "        self.hidden1 = nn.Linear(in_dim, 128)\n",
    "        self.hidden2 = nn.Linear(128, 128)\n",
    "        self.out = nn.Linear(128, 1)\n",
    "\n",
    "        self.out.weight.data.uniform_(-init_w, init_w)\n",
    "        self.out.bias.data.uniform_(-init_w, init_w)\n",
    "\n",
    "    def forward(self, state: torch.Tensor, action: torch.Tensor) -> torch.Tensor:\n",
    "        \"\"\"Forward method implementation.\"\"\"\n",
    "        x = torch.cat((state, action), dim=-1)\n",
    "        x = F.relu(self.hidden1(x))\n",
    "        x = F.relu(self.hidden2(x))\n",
    "        value = self.out(x)\n",
    "\n",
    "        return value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## TD3Agent\n",
    "Here is a summary of TD3Agent class.\n",
    "\n",
    "| Method           | Note                                                 |\n",
    "|---               |---                                                  |\n",
    "|select_action     | select an action from the input state.               |\n",
    "|step              | take an action and return the response of the env.   |\n",
    "|update_model      | update the model by gradient descent.                |\n",
    "|train             | train the agent during num_frames.                   |\n",
    "|test              | test the agent (1 episode).                          |\n",
    "|\\_target_soft_update| soft update from the local model to the target model.|\n",
    "|\\_plot              | plot the training progresses.                        |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "class TD3Agent:\n",
    "    \"\"\"TD3Agent interacting with environment.\n",
    "    \n",
    "    Attribute:\n",
    "        env (gym.Env): openAI Gym environment\n",
    "        actor1 (nn.Module): target actor model to select actions\n",
    "        actor2 (nn.Module): target actor model to select actions\n",
    "        actor_target1 (nn.Module): actor model to predict next actions\n",
    "        actor_target2 (nn.Module): actor model to predict next actions\n",
    "        actor_optimizer (Optimizer): optimizer for training actor\n",
    "        critic1 (nn.Module): critic model to predict state values\n",
    "        critic2 (nn.Module): critic model to predict state values\n",
    "        critic_target1 (nn.Module): target critic model to predict state values\n",
    "        critic_target2 (nn.Module): target critic model to predict state values        \n",
    "        critic_optimizer (Optimizer): optimizer for training critic\n",
    "        memory (ReplayBuffer): replay memory to store transitions\n",
    "        batch_size (int): batch size for sampling\n",
    "        gamma (float): discount factor\n",
    "        tau (float): parameter for soft target update\n",
    "        initial_random_steps (int): initial random action steps\n",
    "        exploration_noise (GaussianNoise): gaussian noise for policy\n",
    "        target_policy_noise (GaussianNoise): gaussian noise for target policy\n",
    "        target_policy_noise_clip (float): clip target gaussian noise\n",
    "        device (torch.device): cpu / gpu\n",
    "        transition (list): temporory storage for the recent transition\n",
    "        policy_update_freq (int): update actor every time critic updates this times\n",
    "        total_step (int): total step numbers\n",
    "        is_test (bool): flag to show the current mode (train / test)\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(\n",
    "        self,\n",
    "        env: gym.Env,\n",
    "        memory_size: int,\n",
    "        batch_size: int,\n",
    "        gamma: float = 0.99,\n",
    "        tau: float = 5e-3,\n",
    "        exploration_noise: float = 0.1,\n",
    "        target_policy_noise: float = 0.2,\n",
    "        target_policy_noise_clip: float = 0.5,\n",
    "        initial_random_steps: int = int(1e4),\n",
    "        policy_update_freq: int = 2,\n",
    "    ):\n",
    "        \"\"\"Initialize.\"\"\"\n",
    "        obs_dim = env.observation_space.shape[0]\n",
    "        action_dim = env.action_space.shape[0]\n",
    "\n",
    "        self.env = env\n",
    "        self.memory = ReplayBuffer(obs_dim, memory_size, batch_size)\n",
    "        self.batch_size = batch_size\n",
    "        self.gamma = gamma\n",
    "        self.tau = tau\n",
    "        self.initial_random_steps = initial_random_steps\n",
    "        self.policy_update_freq = policy_update_freq\n",
    "\n",
    "        # device: cpu / gpu\n",
    "        self.device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n",
    "        print(self.device)\n",
    "\n",
    "        # noise\n",
    "        self.exploration_noise = GaussianNoise(\n",
    "            action_dim, exploration_noise, exploration_noise\n",
    "        )\n",
    "        self.target_policy_noise = GaussianNoise(\n",
    "            action_dim, target_policy_noise, target_policy_noise\n",
    "        )\n",
    "        self.target_policy_noise_clip = target_policy_noise_clip\n",
    "\n",
    "        # networks\n",
    "        self.actor = Actor(obs_dim, action_dim).to(self.device)\n",
    "        self.actor_target = Actor(obs_dim, action_dim).to(self.device)\n",
    "        self.actor_target.load_state_dict(self.actor.state_dict())\n",
    "\n",
    "        self.critic1 = Critic(obs_dim + action_dim).to(self.device)\n",
    "        self.critic_target1 = Critic(obs_dim + action_dim).to(self.device)\n",
    "        self.critic_target1.load_state_dict(self.critic1.state_dict())\n",
    "\n",
    "        self.critic2 = Critic(obs_dim + action_dim).to(self.device)\n",
    "        self.critic_target2 = Critic(obs_dim + action_dim).to(self.device)\n",
    "        self.critic_target2.load_state_dict(self.critic2.state_dict())\n",
    "\n",
    "        # concat critic parameters to use one optim\n",
    "        critic_parameters = list(self.critic1.parameters()) + list(\n",
    "            self.critic2.parameters()\n",
    "        )\n",
    "\n",
    "        # optimizer\n",
    "        self.actor_optimizer = optim.Adam(self.actor.parameters(), lr=3e-4)\n",
    "        self.critic_optimizer = optim.Adam(critic_parameters, lr=1e-3)\n",
    "\n",
    "        # transition to store in memory\n",
    "        self.transition = list()\n",
    "\n",
    "        # total steps count\n",
    "        self.total_step = 0\n",
    "\n",
    "        # update step for actor\n",
    "        self.update_step = 0\n",
    "\n",
    "        # mode: train / test\n",
    "        self.is_test = False\n",
    "\n",
    "    def select_action(self, state: np.ndarray) -> np.ndarray:\n",
    "        \"\"\"Select an action from the input state.\"\"\"\n",
    "        # if initial random action should be conducted\n",
    "        if self.total_step < self.initial_random_steps and not self.is_test:\n",
    "            selected_action = self.env.action_space.sample()\n",
    "        else:\n",
    "            selected_action = (\n",
    "                self.actor(torch.FloatTensor(state).to(self.device))[0]\n",
    "                .detach()\n",
    "                .cpu()\n",
    "                .numpy()\n",
    "            )\n",
    "\n",
    "        # add noise for exploration during training\n",
    "        if not self.is_test:\n",
    "            noise = self.exploration_noise.sample()\n",
    "            selected_action = np.clip(\n",
    "                selected_action + noise, -1.0, 1.0\n",
    "            )\n",
    "\n",
    "            self.transition = [state, selected_action]\n",
    "\n",
    "        return selected_action\n",
    "\n",
    "    def step(self, action: np.ndarray) -> Tuple[np.ndarray, np.float64, bool]:\n",
    "        \"\"\"Take an action and return the response of the env.\"\"\"\n",
    "        next_state, reward, done, _ = self.env.step(action)\n",
    "\n",
    "        if not self.is_test:\n",
    "            self.transition += [reward, next_state, done]\n",
    "            self.memory.store(*self.transition)\n",
    "\n",
    "        return next_state, reward, done\n",
    "\n",
    "    def update_model(self) -> torch.Tensor:\n",
    "        \"\"\"Update the model by gradient descent.\"\"\"\n",
    "        device = self.device  # for shortening the following lines\n",
    "\n",
    "        samples = self.memory.sample_batch()\n",
    "        states = torch.FloatTensor(samples[\"obs\"]).to(device)\n",
    "        next_states = torch.FloatTensor(samples[\"next_obs\"]).to(device)\n",
    "        actions = torch.FloatTensor(samples[\"acts\"].reshape(-1, 1)).to(device)\n",
    "        rewards = torch.FloatTensor(samples[\"rews\"].reshape(-1, 1)).to(device)\n",
    "        dones = torch.FloatTensor(samples[\"done\"].reshape(-1, 1)).to(device)\n",
    "        masks = 1 - dones\n",
    "\n",
    "        # get actions with noise\n",
    "        noise = torch.FloatTensor(self.target_policy_noise.sample()).to(device)\n",
    "        clipped_noise = torch.clamp(\n",
    "            noise, -self.target_policy_noise_clip, self.target_policy_noise_clip\n",
    "        )\n",
    "\n",
    "        next_actions = (self.actor_target(next_states) + clipped_noise).clamp(\n",
    "            -1.0, 1.0\n",
    "        )\n",
    "\n",
    "        # min (Q_1', Q_2')\n",
    "        next_values1 = self.critic_target1(next_states, next_actions)\n",
    "        next_values2 = self.critic_target2(next_states, next_actions)\n",
    "        next_values = torch.min(next_values1, next_values2)\n",
    "\n",
    "        # G_t   = r + gamma * v(s_{t+1})  if state != Terminal\n",
    "        #       = r                       otherwise\n",
    "        curr_returns = rewards + self.gamma * next_values * masks\n",
    "        curr_returns = curr_returns.detach()\n",
    "\n",
    "        # critic loss\n",
    "        values1 = self.critic1(states, actions)\n",
    "        values2 = self.critic2(states, actions)\n",
    "        critic1_loss = F.mse_loss(values1, curr_returns)\n",
    "        critic2_loss = F.mse_loss(values2, curr_returns)\n",
    "\n",
    "        # train critic\n",
    "        critic_loss = critic1_loss + critic2_loss\n",
    "        self.critic_optimizer.zero_grad()\n",
    "        critic_loss.backward()\n",
    "        self.critic_optimizer.step()\n",
    "\n",
    "        if self.total_step % self.policy_update_freq == 0:\n",
    "            # train actor\n",
    "            actor_loss = -self.critic1(states, self.actor(states)).mean()\n",
    "\n",
    "            self.actor_optimizer.zero_grad()\n",
    "            actor_loss.backward()\n",
    "            self.actor_optimizer.step()\n",
    "\n",
    "            # target update\n",
    "            self._target_soft_update()\n",
    "        else:\n",
    "            actor_loss = torch.zeros(1)\n",
    "\n",
    "        return actor_loss.data, critic_loss.data\n",
    "\n",
    "    def train(self, num_frames: int, plotting_interval: int = 200):\n",
    "        \"\"\"Train the agent.\"\"\"\n",
    "        self.is_test = False\n",
    "\n",
    "        state = self.env.reset()\n",
    "        actor_losses = []\n",
    "        critic_losses = []\n",
    "        scores = []\n",
    "        score = 0\n",
    "\n",
    "        for self.total_step in range(1, num_frames + 1):\n",
    "            action = self.select_action(state)\n",
    "            next_state, reward, done = self.step(action)\n",
    "\n",
    "            state = next_state\n",
    "            score += reward\n",
    "\n",
    "            # if episode ends\n",
    "            if done:\n",
    "                state = env.reset()\n",
    "                scores.append(score)\n",
    "                score = 0\n",
    "\n",
    "            # if training is ready\n",
    "            if (\n",
    "                len(self.memory) >= self.batch_size\n",
    "                and self.total_step > self.initial_random_steps\n",
    "            ):\n",
    "                actor_loss, critic_loss = self.update_model()\n",
    "                actor_losses.append(actor_loss)\n",
    "                critic_losses.append(critic_loss)\n",
    "\n",
    "            # plotting\n",
    "            if self.total_step % plotting_interval == 0:\n",
    "                self._plot(self.total_step, scores, actor_losses, critic_losses)\n",
    "\n",
    "        self.env.close()\n",
    "\n",
    "    def test(self):\n",
    "        \"\"\"Test the agent.\"\"\"\n",
    "        self.is_test = True\n",
    "\n",
    "        state = self.env.reset()\n",
    "        done = False\n",
    "        score = 0\n",
    "\n",
    "        frames = []\n",
    "        while not done:\n",
    "            frames.append(self.env.render(mode=\"rgb_array\"))\n",
    "            action = self.select_action(state)\n",
    "            next_state, reward, done = self.step(action)\n",
    "\n",
    "            state = next_state\n",
    "            score += reward\n",
    "\n",
    "        print(\"score: \", score)\n",
    "        self.env.close()\n",
    "\n",
    "        return frames\n",
    "\n",
    "    def _target_soft_update(self):\n",
    "        \"\"\"Soft-update: target = tau*local + (1-tau)*target.\"\"\"\n",
    "        tau = self.tau\n",
    "        for t_param, l_param in zip(\n",
    "            self.actor_target.parameters(), self.actor.parameters()\n",
    "        ):\n",
    "            t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n",
    "\n",
    "        for t_param, l_param in zip(\n",
    "            self.critic_target1.parameters(), self.critic1.parameters()\n",
    "        ):\n",
    "            t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n",
    "\n",
    "        for t_param, l_param in zip(\n",
    "            self.critic_target2.parameters(), self.critic2.parameters()\n",
    "        ):\n",
    "            t_param.data.copy_(tau * l_param.data + (1.0 - tau) * t_param.data)\n",
    "\n",
    "    def _plot(\n",
    "        self,\n",
    "        frame_idx: int,\n",
    "        scores: List[float],\n",
    "        actor_losses: List[float],\n",
    "        critic_losses: List[float],\n",
    "    ):\n",
    "        \"\"\"Plot the training progresses.\"\"\"\n",
    "        clear_output(True)\n",
    "        plt.figure(figsize=(30, 5))\n",
    "        plt.subplot(131)\n",
    "        plt.title(\"frame %s. score: %s\" % (frame_idx, np.mean(scores[-10:])))\n",
    "        plt.plot(scores)\n",
    "        plt.subplot(132)\n",
    "        plt.title(\"actor_loss\")\n",
    "        plt.plot(actor_losses)\n",
    "        plt.subplot(133)\n",
    "        plt.title(\"critic_loss\")\n",
    "        plt.plot(critic_losses)\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Environment\n",
    "*ActionNormalizer* is an action wrapper class to normalize the action values ranged in (-1. 1). Thanks to this class, we can make the agent simply select action values within the zero centered range (-1, 1)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ActionNormalizer(gym.ActionWrapper):\n",
    "    \"\"\"Rescale and relocate the actions.\"\"\"\n",
    "\n",
    "    def action(self, action: np.ndarray) -> np.ndarray:\n",
    "        \"\"\"Change the range (-1, 1) to (low, high).\"\"\"\n",
    "        low = self.action_space.low\n",
    "        high = self.action_space.high\n",
    "\n",
    "        scale_factor = (high - low) / 2\n",
    "        reloc_factor = high - scale_factor\n",
    "\n",
    "        action = action * scale_factor + reloc_factor\n",
    "        action = np.clip(action, low, high)\n",
    "\n",
    "        return action\n",
    "\n",
    "    def reverse_action(self, action: np.ndarray) -> np.ndarray:\n",
    "        \"\"\"Change the range (low, high) to (-1, 1).\"\"\"\n",
    "        low = self.action_space.low\n",
    "        high = self.action_space.high\n",
    "\n",
    "        scale_factor = (high - low) / 2\n",
    "        reloc_factor = high - scale_factor\n",
    "\n",
    "        action = (action - reloc_factor) / scale_factor\n",
    "        action = np.clip(action, -1.0, 1.0)\n",
    "\n",
    "        return action"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can see [the code](https://github.com/openai/gym/blob/master/gym/envs/classic_control/pendulum.py) and [configurations](https://github.com/openai/gym/blob/cedecb35e3428985fd4efad738befeb75b9077f1/gym/envs/__init__.py#L81) of Pendulum-v0 from OpenAI's repository."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/khkim/anaconda3/envs/pg-is-all-you-need/lib/python3.6/site-packages/gym/logger.py:30: UserWarning: \u001b[33mWARN: Box bound precision lowered by casting to float32\u001b[0m\n",
      "  warnings.warn(colorize('%s: %s'%('WARN', msg % args), 'yellow'))\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[777]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# environment\n",
    "env_id = \"Pendulum-v0\"\n",
    "env = gym.make(env_id)\n",
    "env = ActionNormalizer(env)\n",
    "env.seed(seed)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initialize"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cpu\n"
     ]
    }
   ],
   "source": [
    "# parameters\n",
    "num_frames = 50000\n",
    "memory_size = 100000\n",
    "batch_size = 128\n",
    "initial_random_steps = 10000\n",
    "\n",
    "agent = TD3Agent(\n",
    "    env, memory_size, batch_size, initial_random_steps=initial_random_steps\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAABsQAAAE/CAYAAADxMaZGAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDMuMC4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvOIA7rQAAIABJREFUeJzs3Xd8XFeZ//HPMxpJM+pykyXZjpPY6SGBhBASegKEUBJgWdrSy9J+sAtLls0uCwvL0jaUUBJ6CgshgUAoIYVAqtOcxLFT3Ju6rDYaSTOjKef3xzn36s5oJI1lOZLt5/166WXp3rl3ztyZkcb3e5/niDEGpZRSSimllFJKKaWUUkoppQ5XofkegFJKKaWUUkoppZRSSimllFIHkwZiSimllFJKKaWUUkoppZRS6rCmgZhSSimllFJKKaWUUkoppZQ6rGkgppRSSimllFJKKaWUUkoppQ5rGogppZRSSimllFJKKaWUUkqpw5oGYkoppZRSSimllFJKKaWUUuqwpoGYWtBE5HgR2SAicRH5+HyPRymllFJKKaWUUkoppZRShx4NxNRCdwnwN2NMrTHm8vkeTCERMSIyKiIj7uvHgXUiIl8VkX739VURkcD600XkEREZc/+ePhfbHm5EpEJEfi0iu93xfknB+s+LSDrwHIyIyDGB9T8UkS0ikhORd89wX18TkTYRGRaRPSJyacH66Z7vShG5UkR6RGRARP4gIq2B9atF5GYRGRSRbhH5roiESx2niBwjIn904XCfiHytyG3WikhSRH4eWPYSt8/g8XlXYP0iEfmte1x7RORtgXWXFmyXcPtaMtPxEpHjROQmEdnnjsetInJ8YP27RSRbsP+XTPf8KKWUUmp23Oeo8+d7HEoppZRSB0JE3i4it02z/oUisuUA9v9uEbl3ttsrpRY+DcTUQncU8ORUK0Wk7Bkcy1ROM8bUuK/3B5Z/ELgYOA14FvBa4B/BhjzATcDPgUbgauAmt/xAt503wYBnjt0L/APQPcX6XwWegxpjzM7AuseBjwCPlnA/PwFOMMbUAecAbxeRNxTcZqrn+xPA87HPVwswCHwnsP77QC/QDJwOvNiNa8Zxuuf2duCvwHJgBfb5L/Q94OEiyzsLjs/VBduMA03A24ErRORkAGPM/wS3A74K3GmM6XPbTne8GoDfA8e7fT+Efd0G3V8wrjuLjF0ppZQ6ImhopZRSSik1PWPM/xljXuH97C5cXhNYf48x5vjiWyullAZiagETkb8CLwW+66pHjhORq0TkCldpMwq8VEReLSKPuSqVNhH5fGAfq90fx/e4dYMi8iERea6IbBSRIRH5bsH9vldEnna3vVVEjprlQ3gXcJkxpt0Y0wFcBrzbrXsJEAa+ZYxJueo3AV42B9tOSaxvikivO16bROQUty4qIpe5Sp+YiNwrIlG37nUi8qQ7XneKyImBfe4WkX8VkY3AqIiERaRFRH7jqoN2yQG0uzTGjBtjvmWMuRfIzmL77xlj7gCSJdx2izFmNLAoB6yZ6vYFjgZuNcb0GGOSwK+AkwvWX2+MSRpjuoFbgutnGOe7saHWN4wxo24fG4M3EJG3AEPAHSWOFxGpBt4IfNYYM+KO8e+BdxS5rQDvxAaw3pinPF7GmIeMMT8xxgwYY9LAN4HjRWRxqeNTSimlVGkO4kVJSimllFILgn7eUUrNBQ3E1IJljHkZcA/wMVc9stWtehvwJaAWWzk0ij1R3wC8GviwiFxcsLvnAWuBNwPfAv4dOB8bSPy9iLwYQEQuAi4F3gAsdff/yxmGerfYFng3isjqwPKTsVU/nseZCEBOBjYaY0xg/caC9bPddjqvAF4EHAfUA38P9Lt1/wucga30WYRtV5kTkeOwx+CfsMfkZuAPBRVpb8Ue+wZsKPIHN+ZW4Dzgn0TklQAi8gIRGSphrPvjta4t35Mi8uED2ZGIfEZERoB2oBr4RcFNpnq+fwKc68LAKmy11Z8D678FvEVEqsS2UnwVNhQrxdnAbhH5s9h2iXeKyKmBMdcBXwA+OcX2y8S2ctzlAtFqt/w4IBN4b0H+ay3ohcAy4DfBhSUcL8+LgG5jTH9g2bPd49kqIp/VD7dKKaUOF+7v4w6xrY6fEpHXB9Z9wF185a17johcC6zCfsYaEZFL3G3366KkEsdWKSLfEpFO9/UtEal065aIbdE85D5b3SMiIbfuX0Wkw417i4icN4eHTCmllFJHMBFZ6c6z7BM7dch3xbYvvM+dx+gHPi+BloYicrfb/HH3+enNYqeNaJ9uv/s5rnNE5GF34fjDInJOYN27RWSn+2y0S0Te7pavEZG73DZ9IvKrAz9CSqm5ooGYOhTdZIy5zxiTc5UydxpjNrmfN2LDmxcXbPNFd9vbsAHaL40xva766h7g2e52HwK+bIx52hiTAf4HOF2mrhJ7MbAaOAHoBP4YOBlRA8QCt40BNa7SpnCdt752DradTtrd7gRA3OPscic63gt8whjTYYzJGmPWGWNS2BDxT8aY212lz/8CUWxw5rncGNNmjEkAzwWWGmO+4Kq7dgI/At4CYIy51xjTUMJYS3U9cCI2rPsA8J8i8tbZ7swY8xXsMXoOcC35x3q653sb0AZ0AMNuTF8IbHs3NmgaxoZH64HflTisFdjjdzm2HeOfyG+T+UXgJ8aY9iLbbsa2aGzGVhGeAXzDratx4wma6rX0LuDXxpiR4MIZjhcAIrIC25oxGNjdDZyCDdneiA1VP13kfpVSSqlD0Q7sxST1wH8BPxeRZhF5E/B57MVcdcDrgH5jzDuAvcBr3YVgX9vfi5LcZ9dS/Dv2YpvTse25zwL+w637FPZzylJsy+NLASN2HtCPAc81xtQCrwR279cRUUoppZQqQux0KH8E9mDPubQC17nVzwN2Yj+XfCm4nTHmRe5bb2qLvOBphv2WMq5F2PMvlwOLsedS/iQii92FxpcDr3Kfjc4BNrhNvwjchp3mZAX502kopeaZBmLqUNQW/EFEnicif3NXe8SwodaSgm16At8nivxc474/Cvi2uyp2CBjAtiNsLTYQY8zdLvQZws4hdTQ2CAEYwZ7o8NQBI66yq3Cdtz4+B9tOyRjzV+C72HCiV0R+6KqLlgAR7MmbQi3YDw/ePnLY5yB4TILPyVFAi3cM3XG8FPvhZVoisspd1TPiqo5mZIx5yhjT6YV4wLeBvytl22n2aYwxj2FfG/8VWD7d8/09oBL7IakauBFXIeYCx1vcsmrs8W7EzslVigRwrzHmz8aYcWwouRg4UUROx1Y7fnOKx9LtjlHOGLMLW/n3Rre6pNeS2Iq3NxFol1hwH0WPl9t2KfaD4PeNMb8MbLPTGLPLjWsTNjw8oOdNKaWUWiiMMTe4zyc5d3JmGzZ4ej/wNWPMw+7v53ZjzJ4pdrO/FyWV6u3AF9zFYfuwf7u9dslp7EU0Rxlj0sbOw2GwbasrgZNEpNwYs9sYU+xzo1JKKaXU/joLe+7p04FpIu516zqNMd8xxmT28/POTPstxauBbcaYa939/xJ70fFr3foccIqIRI0xXcaYJ93yNO7c2CzuUyl1kGkgpg5FpuDnX2DnPVppjKkHrsSGWLPRBvyjMaYh8BV1QUupY/Pu+0nsVbee09wyb92zXMWX51kF62e77fQDNOZyY8wZwEnYlnmfBvqwc1cdW2STTuwfcsCfS2olthLK323g+zZgV8ExrDXGXFjC2Pa6q3pqjDE1M91+qt0w++e/UJjix6TYfZ0OXGXsnFkp7BVAZ4nIEmwLylXAd42d960f+Bkw4zFxNjL5de95CfZKp70i0g38C/BGEXl0mjF7v/u3AmERWRtYH3yteV6PDYfvnGGcecdLRBqxYdjvjTFfmnKriXHN1fOmlFJKzSsReaeIbAhcHHQK9oKYlRS/AKmY/b0oqVR5+3Xft7jvvw5sB25zLYA+4+57O7ZS7fPYi6quE5EWlFJKKaUO3EpgzxTV7rP5rFPKfktR+JkJ93OrsfOpvxl7UX6XiPxJRE5wt7kEe37jIdf6+r2zvH+l1EGggZg6HNQCA8aYpIichZ1jbLauBP5NRE4GEJF619pmEhE5WUROF5EyEakBLsOGRE+7m1wDfFJEWt0Jg08BV7l1d2KvtP242HkcPuaW/3UOtp2SiDzXVdSVY1tHJoGcO8HyU+AbYufAKhOR54udT+J64NUicp7b7lNACpgqJHwIiIudZyLq9nWKiDx3pvFNM+5KEYm4HytEJOIFgiJykYg0inUW8HHgpsC2FW5bAcrdtpN+94lISET+sWBfHwXucOtner4fBt7pXjPlwEewVzL1GWP6gF3Y+e3CItKAbUG4scRx/hw4W0TOdyX//4QNMZ8GfogNoU53X1diS/q9OdteKiJHuce0EviKd3zcB7gbgS+ISLWInAtchG19GPQu4Bp3hXipx6sOuBW4zxjzmSLH+1Ui0uS+PwH4bPB5U0oppQ5VYltt/wjbYnCxaxX9BPZvfBtTX2xTePHL/l6UVKq8/WIv2ukEMMbEjTGfMsYcg23n+Elxc4UZY35hjHmB29ZQeqW7UkoppdR02oBVUnw+1Nl81illv6Uo/MwE9nNTB4Ax5lZjzMux1fWbsZ//vE49HzDGtAD/CHxfRNbMcgxKqTmmgZg6HHwEe0I/DvwnNsCZFWPMb7H/ub9ORIaxJy9eNcXNm4BfYedg2omt0nmNa2kD8APgD8Amt58/uWW4tncXY+ePGMLO33WxW35A24rIpSLy5ynGXIf9Az2IvaqlH3slMNjKok3YYGfAHYeQMWYL8A/Yiqc+bGn4awNjLTyGWeA12HBml9vmx9g5NBCRF0qJ7RADtmDb8bViQ5YEEx9K3oK9kjmODRK/aowJtva7zd3+HGx4lABe5MbydhEJVkO9HnvVdhwbQn2HiV7PMz3f/4INGLcB+7DVX68P7PsNwAVu3XZsCf0/lzLOwHNwJfa5uwh4nWvfOOY+bHUbY7qxbRCTrgUS2Pnx1mED0HXY5/jjgfv9CLb9Ui92npIPB8r8EZFW7Nxj1zDZdMfr9dj55N4jgTaYIrLKrT8P2Cgio9g5UW7EztmnlFJKHeqqsSdv9gGIyHuwFWJgPxP9i4ic4S4oWSMTc9X2AMcE9rO/FyWV6pfAf4jIUrGV7P+J/TuOiLzGjUmw84JmgZyIHC8iL3MXSyWxn1NyBzgOpZRSSimwF1Z3AV9xF+tG3AW7pSj8/DRX+wV7ruI4EXmbu7j5zdhuS38UkSZ3gXY19vPZCO6zkYi8Sexc6mDP4Rj0c5NSC4YELvhXSimllFJKKXWARORLwIexJz+uAc4ArjXG/FhEPoS9KKYV2A28wxjzmIhchL2wpA74b2PM/4rI67ETyLdiJ2r/iHfhiojsBt5vjPlLCePxb+sq0r+GnR8U4AbgEtdt4Z+x86QuxZ7A+YEx5osi8ixsmHci9qKedcAHjTGdB3KclFJKKaXAzikPXA68EBsg/QJ4FPv55QWB2707uMx9rvoc9kLfD2Iv9v25MWbFVPs1xgQvEi4cR+H+X4Cdq34N9uLmTxhj7hWRZuA67MXghonPaU+JyNewc7bWYwO7rxpjfnigx0gpNTc0EFNKKaWUUkoppZRSSimllFKHNW2ZqJRSSimllFJKKaWUUkoppQ5rGogppZRSSiml1CFMRFYVzNlZbP5OpZRSSqkjnohcOcVnpivne2xKqYNPWyYqpZRSSimllFJKKaWUUkqpw5pWiCmllFJKKaWUUkoppZRSSqnDWni+B3CglixZYlavXj3fw1BKKaXUNB555JE+Y8zS+R6H0s9OSiml1KFAPzstHPrZSSmllFr4Sv3sdMgHYqtXr2b9+vXzPQyllFJKTUNE9sz3GJSln52UUkqphU8/Oy0c+tlJKaWUWvhK/eykLROVUkoppZRSSimllFJKKaXUYU0DMaWUUkoppZRSSim1IInIShH5m4g8JSJPisgn3PJFInK7iGxz/za65SIil4vIdhHZKCLPCezrXe7220TkXfP1mJRSSik1PzQQU0oppZRSSimllFILVQb4lDHmJOBs4KMichLwGeAOY8xa4A73M8CrgLXu64PAFWADNOBzwPOAs4DPeSGaUkoppY4MGogppZRSSimllFJKqQXJGNNljHnUfR8HngZagYuAq93NrgYudt9fBFxjrAeABhFpBl4J3G6MGTDGDAK3Axc8gw9FKaWUUvNMAzGllFJKKaWUUkopteCJyGrg2cCDQJMxpsut6gaa3PetQFtgs3a3bKrlSimllDpCaCCmlFJKKaWUUkoppRY0EakBfgP8kzFmOLjOGGMAM4f39UERWS8i6/ft2zdXu1VKKaXUPFtwgZiIXCAiW9zkp5+ZeQullFJKKaWUUkopdbgSkXJsGPZ/xpgb3eIe1woR92+vW94BrAxsvsItm2r5JMaYHxpjzjTGnLl06dK5eyBKKaWUmlcLKhATkTLge9gJUE8C3uomSlVKKaWUUkoppZRSRxgREeAnwNPGmG8EVv0eeJf7/l3ATYHl7xTrbCDmWiveCrxCRBpFpBF4hVumlFJKqSNEeL4HUOAsYLsxZieAiFyHnQz1qXkdlVJKKaWUUkoppZSaD+cC7wA2icgGt+xS4CvA9SLyPmAP8Pdu3c3AhcB2YAx4D4AxZkBEvgg87G73BWPMwDPzEJRSSim1ECyoCjF0glOlSpLNGfpHUpOWtw+Okc7mim6ztSdO73DygO97aGycZDp7wPspxd7+MYaT6bxlY+MZ9vaP7dd+nuiIMTg6XnRd++AYnUOJkvbTFUv4jz2VyfLw7uL/dzLG8OdNXfzyob385ameafeZyebY0z9a0v0fTMYY7t/Rj229P9mm9tgz9rwX0zYwxo59I/N2/wuFMYbbnuzmt4+1s25736T1T3TEiBe8Z6ayfvfAlM+3Ukodidbt6GM8U/xzlFJKqfljjLnXGCPGmGcZY053XzcbY/qNMecZY9YaY873wi1jfdQYc6wx5lRjzPrAvn5qjFnjvn42f49KKXUwPLZ3cNJ5JKWUClpogVhJdHJTdaS7YX0bL/76nXkBxUgqw3mX3cUN69uLbvP+q9fzlVs2H/B9/92V9/P1W7cAsKtvlAu/fU/RcG4uvOGKdXzvb9vzll155w5e8517yOVKO5FvjOEtP3yAH96zs+j6T17/OJf8euOM+8nlDBd86x5+dt9uAP68qZs3XXk/7YOTw7nN3XE+/H+P8m83buL916yfNnD73YZOzv/GXdMewzu39HLuV/4654HUd+7Yxk0bbMv8B3cN8NYfPcBDuyaHfPFkmtd//z5++dDeOb3//fGFPz7Fv9zw+Lzd/0LxRMcwH7z2Ef75V4/zth8/yL74xOsmmc7yhu+v49oH9sy4n8fbhvi7K+/n3iKhmppfIvJTEekVkScCyxaJyO0iss392+iWi4hc7uZd3Sgiz5m/kSt1aHuiI8bbfvQg/3Pz0/M9FKWUUkopNQvpbI7Xf38d7/3ZwzPfWCl1xFpogVhJE5zq5KbqSLe5O85IKsPg2ETVU+dQglQmV7SKJpPN0TGUoH2gtEqoqYy7/W/tiQPw0K5+nuoaZnvv3FfuDCfT9I2k2DecHxTt7BtlOJmhr8QQbmB0nJFUZsrAaW//GLtLqNDaN5IilkjTG7dVdkPu2O8dmByIxZMZAP7h7FUAdEwTiO3YN0I6a4rux/NU1zAdQwn6p6hym62frdvNrx+xAapXpbanyDhiiTSZnGF33/xVsvWNpBiY48d/KGpzAew7zj4KIO93QHcsyXg2N2U1ZJD3mt+zn9WW6hlxFXBBwbLPAHcYY9YCd7ifwc65utZ9fRC44hkao1LzYiSV4TO/2chIKjOn+01lsrz1Rw8AzNlnmkw2xz9eu54nOmJzsj+llFJKKTW9nOuAsrFdP38ppaa20AKxh4G1InK0iFQAb8FOhqqUCvAClpHkxAmhrljS/Ts5fOkbGSebM3QNH1gg1h1LYgx0DNr9eP/Gk3N7Ygqga8g+nuGCffe4to/ThUx5+3HHpdgYM9kcvfEk3bEk2Rkqzrz786q0Eulc3jiDEu42J7fUA/a4TaXbf96mvo039sT43B3nxHiWgdFx/3F1uMdR7PF4Jx5LPeYHQzyZOSivs0ONV2145upGgLz2iN66sfGZKwm999F0r001P4wxdwOFpZoXAVe7768GLg4sv8a1BXoAaBCR5mdmpEo98350906ue7iNH09R9T1b63b0z/nfmN39Y9z6ZA8fv+6xOd2vUkoppZRSSqnZW1CBmDEmA3wMuBV4GrjeGPPk/I5KqYXHO/EdDIt6pglWvJCsJ5YqudVgMe1DtpqkYyiBMYZ2N454au77M3uPsXA+JO/xlRrOTOxn8omu3niKnIFMzviVX1PxgqKECxu8cKpYO0TvNkcvqQamDx287adrqzicsMdgNDV3LRM7YxP3a4yZdhyjLhBrH5y/QGw4kc4LgI9U3bEkkfIQKxqrgPzfAR37EYh1lRDEqgWlyRjT5b7vBprc9zr3qjqieJ9gdPpDpZRSSimllFKzsaACMQA3MepxbvLTL833eJRaiCaqntKTlhULX7xl49kcA2OzbzvnVYSlMjkGRsf98ORgBBVeYBMMsnI5M1EhVmI40z08+Vh5gmHAdIFUcL0XNnhVYJ1FjrdXRba0tpLqirJpQwdvfKVUiJUSdJSq0694y9E/Ou6Hpp1FKgxHXBA33xVi49ncnM+jdqjpiiVpro9SFwkD+e+PThfajpVQSej9Tug+wKpR9cwzxhgmcoGS6fyr6nAgB7DtX57qmfFv/cGwc9/8tRtWSimllFqIvn7rZt7504fmexhKqSPUggvElFLT81rdAXlzaHjBSm88RSaby9smGLYcSIu0zkA7vY6hhB+QFLY1nAudRarPBsbGSWeNf/+l7WfqlonBY9FRpFVgkHd/iXRBIFasQsytq6ooo6k+MmXoYIyZttWlZ9iFeYn03B3n4Lg7BhP+cSoWzHmBZzyZ8cfyTEpnc/4xnet5Yw41XbEEzfURaiPlQH4YvT8tE7VC7JDT47VCdP/2uuUlzb0KOv+qWniyOTPrqvWZtkoXfA4CeP8163ntd+6d1f0ppZRSSqm5872/7eDurXqRnlJqfmggptQhJljBEwx5ut3ybM6wbySVt40XlsGBnQDvcC0TAdoGEn4bwYM5h1j+YwwEWKVWiMWmDu2CIVSpFWL+HGLjuSm381omRsvLaK6PTBlCDoyOM55xc5GVUCE2ly0Tg8evfTDhP44u10IxaDQ1OXR5JgVfA0f6PGJdsSTL6yPU+hVigTnEYqUHYt2BitLC51stSL8H3uW+fxdwU2D5O8U6G4gFWisqtaAde+nNvOkH9+/XNuKViE3ze6ttYIy1//5nbljfNmld/+jsq+SVUkoppZRSSh36NBBT6hATDCSCJ8O7h1NUhu1bujBc6Yolqam0J9C7p6lEmvm+k6xebOcu2tA2SMZd2T1yEOYQ6wjM/eWdsPce19LaytIrxNw2xcbYFUsSLS+jLhKeMejx7turVEoGKsQKAwXvNpHyMpbXRacMxLx91kXCfgBYjDeHWGIOWyZ2DCWpda+JJzpjpDI5VjRGGR3PMpzID53igUCs1CByLgVf50fyPGKZbI7eeIqW+ihVFWWUhaSgZWJpgZjdT5LqijLGxrMHpcJTzZ6I/BK4HzheRNpF5H3AV4CXi8g24Hz3M8DNwE5gO/Aj4CPzMGSlZu2RPYP+9+lsjqe7hv2fB0fH+c4d2/KqyKSEponbeuMA3Lxpdtmw2f+OpEoppZRSSimlDhEaiCl1iMkPxPIrxE5trXff54cr3bEEJ7XUEQ7JAVaIJTi5pZ5oeRkP7Z44iXUwqnY6AxVvXsDkVbqdsaqx5EDMOxbJdG5SC6XuWJLm+ggtDdEZgx7vuCcK5hAbLRIoJNNZRKAyHKK5PkJPPEW2SFso77l49qpGeuPJSa0uPRNziM1ty8TjltdSXVHGw7sGADjzqEa7riA0DVaIzcc8YsGArthccEeKfSP2dbS8PoKIUFMZ9o+HMabkOcT2jaTIGThtZQNwYG1U1dwzxrzVGNNsjCk3xqwwxvzEGNNvjDnPGLPWGHO+MWbA3dYYYz7q5l091Rizfr7Hr9RsffXPm3nVt+9hV5+dc+s/fvcEl92+lft29E267aEeWeVyZsbq3Ef2DPrzpiqllFJKKaWUmhsaiCl1iOkYSiJi56fygpJkOsvgWJrT3QnuYhVirQ1Rmuqmbt83E2MMHUMJWhujtDREeLIjBti2gHMdiOVyhu5Ykjq/LZzdf3csQVlIOG1lQ0nzWXn7qaooy9uPpzOWoLkhworG6LRBTzKd9dssJdM2tApWaxVWlyXGs1SVlyEiNNVHyOYMfQVtLGGiZeMZRzWSM9ATn3wbO277OEfnsEKsM5agtSFKa2OUje32uTxj9aK8cXlGUhkqwyEqykLzEogFQ7D4ETyHmPe+bmmIAFAbCfuv6aGxtB/SzlQhNhHEer8vnvnnVCmlCj3WNgRAv/t7OerC/Uw2UCE2c4HYnNjcPXzQ2slmsjmOufRmvvznzdPe7o1XrOPl37jroIxBKaWUUkoppY5UGogpdYjpHErQVBuhsarCPxnuXUF8/PJaIuUhugKhRS5n6B1O0VQXobk+MusKsb4RO99VS32E1sYqv13icU01c97Grm8kRTprOGF5HTARiHTFkjTVVrJyURSYuX3fwNg449kca5fV5O3H0x1LsrwuSktDdNqWid4xq64omwgd0lk/sCsMFBLpLFEXwjXXRfL2UbjfcEj8yr6uImPIZHN+EDZXLRNzOUPXUJKWhiitDVHGXWXaGatshVhHQfvGkVSG2kiY5obIvLRMHNY5xICJefWW19nXf22k3D82XlDZ2hBlbIbQ0AvFn72yMe9npZRaiIq1MJwqq0pnczzZMVx8pbN+9wCX3bZlyvX3be/ngm/dw+82dOzXOEvlfX66et3uGW+rLW2VUkoppZRSam5pIKbUIaZzKEFLQySvXZp3Qru5PkpzfZSuQIsdLxRqro+wvD7itx2czf0CtDZW0eoqVBqryllWF5mxUmu/7ys2EfDBxAmhnuEkTfURWhuieWOPA6Z0AAAgAElEQVSaihcgrG2y+wmGKd58TF7LxOFkZsp2fN79HLusxm9HlxzPcqwL2goDpEQ6S6TcBmLL6+2xKhY6dMeSNNVFaG2M5j3uoJFAuDFT5U+p+kZTjGdztDZM3HdlOMTxy2ttW82hyS0TayrDtDZMX0l3sAznzSF25LZM9IJXv0Is8DvAC1yPXVbDWDo7bWWDd9tnraxHpHhYq5RS8y1YDPa+qx5m9Wf+RMzNqTnVPF9fu2Uzl92+ddr9/t2V9/Odv26f8f43d8dLHqtSSimllFJKqUODBmJKHWJsIBalNhL2wxIv5Fpeb6vAguGL9723riuWmFUboGAFihdItTZG3Un5ub2C2QugjlueH2R1uTm/vPufKZzx5sI6rskGV8FgpW9k3J+PqcXtb6pgwLufY5ZUk0znyLl5zVY2VlFeJpOCuWQ6S9QFYs1+IDZ5rF646d2mWIVYcP6suZpDzKvyshViVYB9XstCQlPd5CrCkWSGaheIzRRCHgxxrRAD7OszWl5GfbQcyG+Z6D0va5fVYMxEa89iumMJKsMhltZUsqSmUivElFILmjFwx+ZeANoHx6a9rdcCGPL/XjyyZ+DgDG4aT3VNX6mmlFJKKaWUUuqZp4GYUoeQXM7Q6eYDC54MD4Zey+sjecFKl189FmF5fZRkOudfYb0/vBCltSHqB0itBcHcXPFO7p/gB2JpjDF+i8MlNZV2PqsZ2vd5x+W4IhVinYFqG6/ibaqAzas0O3qJDdZSmRyJdJbqyrJJxxtsa0OvZeKi6goqykJ5VXv++IaTNNdHqY2UU1sZLhrIBUO8uaoQ6xzy5qKK+tVG3nPa0hCZFHqNuAqxloYovfEU45mpw5aDwauCqigLzflr7VDS7QJhcZPo1EbCxFP22HQOJagIh1jhKv6mC0+7AvtpqY/47wWllFpIvN9177t6/aR1U13X0zYwEZit3zPof//GK+6fdNuD/bds576R/d5mW0/8oM1dppRSSimllFJKAzGlDin9o24er4YoNZHyvHZpNZVhairDNNdH6ImnyLo5KrzKJK9CzLs9QCqT5YGd/azb3jdllUg8mebOLb1saB+ipjJMXTQcCMSqqI2UM5LK+CdwjDGs2zH1/oLS2RzXPrCH69e3sak9RncsyXgmR+dQkqqKMv/kfjyZIZ7KMDaeZXl9JaGQ0NIQob2ECrGKshCrF1cD5M115oeIdRMB31QBW+dQgqW1ldRH7ZxhiXSW5Lhti9hcH/UDJk+wZaKI0FQ/uQrHGOMHEwDNRYIomH0g9kRHjL39+VfSj41n2NoTp2PILm9piPrH2BtHS0N0UkDiBWKtjVGMmTxn2sEwnslx04YOjDEMJzLutVc+aT6VrliCPf2j9I2kJu1jrk4qzraqcq4k01mS6SydsQTNLsAEO4fYSGAOsZb6CNWV9jU63WulO5b0W3kuL6goVUqpg613OMng6Lj/cypjf18dyO/ZbM7w6N7Boq2Hf3zPzqLbXHb7Fk787C2852cPTbvvvf1jbO05+O0TH9s7yMu/eTc/uXfXQb8vpZRSSimllJrKVfftYnff6HwP46AJz/cAlDrSpbM5zv/GXYyNZ1mztIb/d94ann/MYm5/qoee4SSveVYLjdUVGGO45cluwIYXwcqsnuHgCe4o2ZyhbyTlt78Lh4Ql1ZV581k110d471UP8+jeIQCi5WV8+Q2ncvGzW/2x7eob5X1XPcxO90vwpOY6RISVi2ybvRWNUcazObI5w9h4luFkmn+7cRN3btnHW567kq+88Vm0DYzxLzc8zntfcDSvPHm5v+9czvDpGx7ndxs6845HSKC8LMTKRTZsAxvKTVTBeZVM0aItBgH2xVPcu30fj7cN0VRfSV10Yj+eYOVcXbSccGii9WHvcJLLbtvK5u5hBsbGGRpNc8zSar/qK5HOkkhnqaooo7Uhyp82dvGqb9/D285ayTuev5pEOkeDu0+A5room7vifPQXj7Kjd4RwmXBKSz3jmdxEIFYfZWffKLv7Rlm1qIpQSNyYM/7z41X9fPZ3TzAwNs5/X3QKjdUVRY/BJ657jDXLavjBO84kmzN87ZbN/OKhvcSTGSrKQjZgioT9lonNDV4wFqU71sX169t4yfFLWVYbYTRlWyae1FwHwId+/ijvOWc1v32sg6OXVvM/rz910v3Hk2m29Y7wnFWNecs3dw9z/45+nu4apmc4Rc4Ynrt6EeeuWcyzVjRQXmav07jj6R4+cd0GVjRWEU+mqY2EiZSX5VWIrdvRx9t+9KD/c1NdJe8592g+9OJjGRob54Vf+xvPP2Yxn3vdyX6bzeDxedkJy7jo9PzX+x8e7+SoxVWsaKwiUh7iO3ds55Ynu/nJu87kvBObih7r/pEUf3m6h00dMcZSWb78xlOpDJfx6RseZ92Ofl51ynI++KJjWFZnn+t0Nuc/TrAngV/33ftYWlvJx162ht9v6OTx9iF+8f6ziVaU8eGfP8Kje4cYz+S48NRmfzuvStQLV1saolS512ixQOyq+3bRGUuyZ2CMF6xZ4j/f67b3+7f5zSPtLKqu4KUnLCv6WJVSqhSZbA4Deb/rPGf9zx15P48kM1TWlPmfR1xhWN4cYp5bn+wBwACX3baFaEUZa5fV8oFr1vOi45YWHcvPH9hTdHl3LEkineVvW/bxznNWT/lYXvT1vwGw+yuvnvI2c2Gvq257PND2USmllFJKKaWeSYnxLJ//w1Msu3MHD/37+fM9nINCAzGlSpTKZKkM25PNsbE0mzpi7Owb4ZUnL6epLsLm7mG+fssWjl5SzctPauJ5xywG4MGd/ZywvI76qnKGk2ke3DnAy0+aOLHeNZRkT/8YZx7VSNvgGG/70YMcs6TaD6G++KenObW1npwxPLZ3iNNWNnDumiU8snfQr5bpiiVZ7k62N9dNVIE11dnqj6a6CKGQ+OHLF//4FFlj6BpK8pU3nMrKRVV8+y/b+KdfbeB7f9vO0tpK0tkcm7vihMuE77/9OZSXhThmqa20am2IcsXbn8ML1i7h94/bQGskleG/fv8UD+zsZ1F1Be2u2mrdjj4e3DXAg7sGeMfZR/HFi08B4Ku3buZ3Gzr51MuP48JnNbOtJ07/6DjdsSQ79o3w/GMWU11RhogNhSYquuxjWFJTycZ2e/JsNJXhfVc/zH+97hSOX17LD+7awY/dFdYvOm4ptRH7qy7YMrFryM6j1FBVjoiwvH6iQuuWJ7v51fo2zj5mEc9Z0kgskebCU5v9qq94Mk0mZ4iWl/H2560inc2xbkc/f9zYxTuev5rkeJZo3UQlz/L6CA/tHqB9cIxz1iwhmc5y42MdAH64eFxTDXdt3cdL/vdO/uHsVfz3xTZkGnbtLZfXR/yQ46+be+kYSvDYnkH+7wNnc/SS6rzXqjGG9sEEFe71eu/2Pn5w905eeXIT565Zwk0bOlnZGLXVa3WVfPqVx/OaZ9mg5UVrl3D9+jYu+fVGTmqu4+ZPvNBWiEXCnNJaz4/eeSb/duMmLvnNRmDiBF6ha+7fwzdv38qGz72CGle1NDg6zoXfvoecgSU1FbQ0RElnDd/8y1a+cTtUV5Tx+dedzJvOXOm/ftoHx4gnM34gFgw1t3bbK/b/++JTSKaz/OKhvdywvo0PvfhYdvaNEk9muO2pHu7f0c/fPv0SltRUAva9fJMLYoOB2LX37+Gn9+VfmV8Ztidzt/WOcN6JTfz8gT3c+Gg7N37kXAA+fcPj3PhYB9mcoaIsxHg2x7vOWc1pKxtYt6OfsfGMv8//eM1J3Lmll4/836Pcc8lLWezGMzA6zqaOmP/cejpjCY5dWsOegTHSWdumc82yGn99baScTM6QTOfoHEpw7polVFd4FWKTWyb+8O6dfvVEU91EhVg8lXGhYzmX/3Ubp7bWayCmlDogF3z7Hrb3jvghUjZnSGWyVFVM/q/HbOrC9g6M8aeNXQC8+cyVAGzYOzjdJkoppZRS6jCnnacn7O4bZXvvCOefVPzCXqWmYtz/0OLJw3fKEg3ElCrBbU9288FrH+HkljpqI2Ee3j0YaEmY5JILTuD2J3u4Y3MvFeEQv3+8k4f+/XxGUxne9uMH+cR5a/n4eWu5/uE2/vtPT/Pgpef5J6TbXfu6f375cTxnVSPf/MtW7tvex1ffeCqntjZw/fo2tvbEiSczXHrhCbz33KMJl4WorQwznsmRymTpiiV44Vp7ZfSiGlsxNDhm2xENjI2z2C1bXhfhky8/jgd39TMwmuaq9zyXc1ylyPOOXsQP79nJhr1D9I+OU1EW4mUnLuNTLz+eVYurJh2TV7lKlWAV186+EV64dinlZcIWF1Z0DiURgYtOa+HaB/ZwyQXHU10R5up1u3ntaS187GVrEBGOXVoz6T4AaiptFYw3v5cX6i2qrqB/xD7G7b0jPLBzgHU7+jh+eS2dsQSrFlXx7beczlGLqykvCxEpDxEPVBd1DCVodaEQuFaBrvVhx6Cdj+kX7z/br9QCuP0pe2X6gGv1FCkv48zVizhz9SLed9XDftVZIj0xhxjA25+3ipaGKO99wWqW1drxD42N8+jeQV58nA0e/vWCE7jw1GY+9/sn2dA25G/r/QFqqqtkcNSGQbFEmheuXcI92/r4/YZOPnH+2rxjNjSWJpXJ0T5oX1t7+224+l+vO4Xl9RHe+fzV/m1FhI++dI3/8zlrlrD+38/n0t9u8k82ei0TAV5+UhPPXd3I1p4R/vB4Jzdt6Cj6vO3pHyWTM+ztH+OkFltZ1j6YIGfgm28+jdc/e4V/28HRcR7Y2c/n//Aktz/Vw5vOXOm3bewYSjCcTFMXKaciHMoPNWNJKsIh3nbWKkIhoXMoya8e3gtAj3suLrngeL52yxY2d8V5wdpKt862VyxsURlLpGmqq+Sa9z6PzliCobFxzjxqERdefo8fyD60a4BH9w6RTGcRgRseaeelxy/lkgtOwBi48PJ7aBsc4+SWOrqHk3z4xcdy21Pd7HHB4Ya2IcbGs2zrHfEDMe+1/d8Xn8J4xlZcfunmp/12iCPJDBed3sJHXrKGpbWV/ni9oHdwbJye4SQt9RH/dVdYIZbO5ugeTvKmM1bQ0hD1K0G9dqGdQ0nWLgvTNZTkgkAlp1JKzcb23vz5s7yLB4pVWT3REeOLf3zK//mNV9zP7q+82q8UK8a7ICKo2PmPax/YM2XgNs3u3frpb3Hnll6OX15Lc3206PqZtp+KziGmlFJKKXWAZvcx7LDykv+9Ezj4XQ6UOhRpIKZUCTa7Ey/VFWFiiQwfevExnHPsEi759UbaBidO3C+pqeSdzz+Kb9y+lWQ6S8dQgmzO+JO8e1Uve/rHJgIxt6y1IUq0ooxLLzwx774//7qTi47JC6IGRsfpjaf8uaDq3HKvsmg4kfaXiQgfP28tsHbS/sJlIT7ykjWTls+k1gUlw8kMXUNJzjl2CSER7tyyD2OMnX+rppJXnryc323oZE//GEtqKkmmc5x19CI/kJpKXcRW1rUPjlEWqHJbUlNBPJUhlcn680f1DE/8u6IxyrMD7fpqA3OugX2+VjROBH2tDVEe2jUA2OektSGaF4aBbVsIE4FYMPSqi5aztde+ToJziAE875jFfsWgp6GqgpedMHGlTrgsxLNXNXLaiga/6s4eVzvmproI7YMJ0tkcI6kMz129iEf3DObNMebxgrl4MsNwMk2bC/iWBcKU6YRCwqrFVX7lUDKd8yuPvLGfdfQi7tm2j5FUhlzOTDpW3hj2DkwEYt7cY4XhZ2N1Ba86tZlfP9Luv5+6AuFkPJlhSU0FFeEQ/X0TFWnevFnefS+vr2R0PEs8maZn2G7/fHfcg+GXF0AVzv0WT6ZpiFZw/PJajl9e6y9vro/4Y/f20x1LUubu91WnNHNic53fzrFtIEFXLEk2Z1jRGGVFY5X/Pm8bSPjH5eyCsZ2+soFTWut5cKdtYejtzwskvWpCjxeIbesdIWeYtmVidyxJzsAZRzXylrNW+cu9VpIdQ2M0VpUzns3R2lj85K5S6sh004YOjl1awymt9fu9rTdnoVcVXcxlt21lx779608fjIx+tb5tytt99ndPTLku2LJ5537eP8C7f/YwAD9995l5f8+LWf2ZP/Hxl63hk684fsrb3LVl336PQSmllFJKKaXU/pnc2F8pNUlvPElDVTnXf+j5/PkTL+TTrzyBc9cs4ajFVXS4Khyv4sg7wdwVS/on3r1wwDvx3RZoM9cxmEAEmhsi7A/vZPiW7jjG4Ic79dGCQCyZ8ZcdDN44umNJ4qkMzfURml17v3gqQ1csSXND1K8y29M/xm5XsbS6SOVZsf3HkxnaBhK0NEQIu/lIgu3m9sW9ICzp/9tUl388ayvDfotJmAi9PC0NEbqHk2SyOdqHEpPmnAKIVoT8+4SJgCw4TsC2TAys2x8rF0WJJdLE3PMXT2aoriijpjJMYjzrL2+oKp8U8nm84wD29dU2MMaKIgHfdLxKtl2udWdNZPL1E7WRMDkDo0Xa800EYhMnGb1xeXPZFVrRGPWr2oIBlNfOr6Yy//F2DiXyrsz35pfrjiXpHk5RXiac2FyHCH7FmbcdQPdw0q/0BHus66KTH+fy+qhfIRbctiuW/3hqKsM0VpXTNjjmB2ArF1WxsjFK+8AYxgTC8cDvgGAoDhPHOp7M+PPz1VROfg97QbdXKWEDseItE73fRYVh10r3c8dgwr9NyxTVDkqpI9MnrtvAa75z76y2PfvLd3D9w1MHVjDRkiPof25+evptilRRHUhLj2CF2v5671XruX59G7e5eV4Bduwb4ft3bs+73eV/zf85lcnlVVlPFxrOpVQmy2jq8G1/opRSSimllFLT0UBMqRLsi6eKVtfYE/jeXEcJVjRE/RZkHYMJOtw672S8dwK9bTC/ymVZbaU/P1mpvAoxr3rNO5nuBVRe+BNLpIue5J8r3ji8FonNDVE/IOiOJemM2Sqeoxbbea72DIyyxw/EqovssXD/YeKuQmxFw0SAtrjatoHsHxn3K8S6Y0mMMfQOp1hWV1lkP/aYjI1nGBgd96vqAFobqsjmDL3xFB2DxQOxSGGFWJFAzBjjWibO7tfrShdsesHJcMKGQdWVYcbGswyN2UCoPlpObSTMcGLqMApcIDY4Nqm6aCbe6927ar6mcvLrc6Jd5uQxeAHSnv6J13pXLEk4JCypLl6ptqKxingyQyyR9ue6si0TbVBVGwnntb3siiX99xtMzC/XPZykZzjJstoIkfIyltRUFq0Qs8/3xLEadsFboea6CF0xG5Z2B0LX7iIB38pFVbQNjPnv8RWNUVYustV2sUTaXx6ce61jKEFVRRkNVfa+6wJtSL0qsakCSZj4HTBdhVhHQejmWVJTSUVZiPbBhF8xpxViSqn99dnfPcEVd+4ous6bcxJge+/kVoe53ORtfnj3Tu4IzKm4UCQKfrd6Lvn1Rj547SOADcPOu+wuUpkiD6zAJ67bMGlZYdQXG0vzuZue8D97BJ3z5Tu45v7dM95P0Ou+cx8nf+7W/dpGKaWUUkoppQ4XGogpVYLeeCpv7h7PisYqeuMpvz1ia2PUD1k6hsb8k/BdQzaoCbaR80wVvszEm9Pp6a5hNxa7j0h5GZXhkF9JNJxIU3cQK8S8E/Vbe9xJeVchBraapmsoSXN9lJrKMEtqKtjbP8bu/jHKyybaH07HVkFlaBtMsHLRxHHy5kXrG0nR5+YS64knGRpLM57N0VQbmbSfEVdd5IUDwUCspWGiIqpvJJW3zuMFYIPeHGIVwUCsnGzOMJzIkMmZA6gQs8GVVynlVS1Fy8tIpLP+3HANVRXURcuJpyZXiHUHK8SGErQN5B+7UniB4k6vQqxIhVJtoJIpaDgQ5ARf690xW7k3VaWaN8ad+0b8kNO2TLRBVW0k7LdozGRzdt6sQGWlF4h1xZJ+my6wQVEwJAyGY8G2ifFkhroiwVNTfYR9Iyk6huwcaBP3YfeTF4i59ojtgwlCAs31Ub96c8e+Uf+5CR6XTleR6LUP9d7bI6mMfxy91qRB3ntvS8+we5wRv7XlpEDMq/4q+F0TCgmtjVHahxJ0uPkMC2+jlFJTGRgdZzSV4doH9vDVWzZPGRh5zv/G3ZOWPeU+xxSabiqtYuHQwXbLE12c+J+38ERHzJ+vspjzLrtrv/Y7ODruV0UXc9oXbuPq+/fwmUCwCLZ7QWcsyX/e9OR+3d+Wnsmh5EIUT6a5Z5u2kVRKKaWUUkrNLQ3ElCpB73DKbyEX5IUmG9qGGM/kWNFoq6NEoGNoomViIp1l30jKP8nfPpBfrdLauH/VOxCoDumK582tBbZ6aDiRJpnOksrk/IqTg8Fv3dgzUaXiBQRbuuMk0lk/tFi1qIrd/bZCbEVjld/+cKb9942k2BdP+dVTAItdlVH/SKBlYixJj6v4mdQyMVAh1j40ORDzQsmHd9t5xIpVyXhzhg24Kq3CCjHArziKzDYQ8yvE7Bi9qiWv8scLdhpchVjx6qwES2srqQiH2Nw9TCyRzjt2pfACxZ37RgConrZCLD+U8+b/qgiH8oKfrkBIVYwXHD2yZxBjYO2yGkbHs6SzhtqIrRAzBsbSWXriKX/eLI8X4vXEbIWYF5C1NkT89yLY91y1O57BcGw4WTw8bq6PYIx9n3u6Y0m6YymqKsrywqoVi6J0DCbY2z/K8roIFeGQ/zp7YGc/xtjXjTdXmjee4Out2gvEkhlGktNViNmxbusZoaGqnKqKsP8aHStoh9UxaOc4LPa6bG2I+hVitZXhg9piVSl16DPG8L+3bmFz9zDP+eLtvOyyO/11J/7nLc/IGAbHJl8MMte2FQRHd2214czG9hj/+ptNs95vsFUvwFAizdaekRm3C17o8HTXMGd96Y5Zj+FQ8E/XbeAdP3korw20UkoppfbPpvYY1z009YU8803bOCul5oMGYkrNwBjDvpGpK8QAHtzpQpSGKOVlIZpqI3QMJvJOtj+2155MLy8Tv21aNmfoiiWKViPNxAu5duwbYXldJC9cqouWM5xMM+yCioNaIeYqUvb0jxES22pvWa0NBR/dOwjgz/O0enE1e/vH2NM/xlElzB8GNmjqGbaB14oiFWIDo+Psc0Hj6HjWb/E3XcvEiTmbJsbQXBiIFamSqSq3j9WrEKsqqBADW00IE+HZ/qqvKqcuEvaDpHgyQ20kTJULSbrca8qbQ8ybKy6oK5akpT5Ca0PUf23ub8vEhqpyKspCgZaJkwOZuikqxLwr3Z+9soGOwQSZrG0bFQypivHeBw/tsmM+c/WiwH2V+1Vq8WTaf28FA7FIeRmLqivocu0MvVC0uT5K51DCn3OmcyjBc45qzBurMcY/1oW8EO/RPfb1XFEWci0TEy4An6h4W9lYxXg2xyN7B/3fD96xv39HPwBnHb2IffGUX0nRMZjIexwV4RCV4RAjqYwfNhY7/t5YU5mcP+9XRThEeZkwlp5cITZVK8QVjTbEay8Yh1LqyNYbT/KI+70HsL13hBvWtzE6nuW7f9vOm668H8D/G+3525aF1+pwNmbTsnF778zB1qaO2KRl63b0lXwf23rivOrb9+zXuA5F29yxTKanrzpUSh0ZROSnItIrIk8Elv1KRDa4r90issEtXy0iicC6KwPbnCEim0Rku4hcLsEP8kodhl773Xv5zI2zv5DnYNM2zkrNjVue6OK3j7XP9zAOGRqIKTWD4USG8UxuyjnEAB7cZU90eyecWxvtCfjOoSTHLLHzZHnh0GkrGugeTpLKZOmNJ0lnzexaJrqT4ZmcmXSiuy4SJpZI+/NLHcyKj1BIqKkMk80ZmlwwVxEOsaSmkkddCNjsVYgtrqJrOMnOfaMlzR8G5M3pFKxyqqkMU1EWom/UVt6VuTZ8G9vtiaZiLRPjgZaJ5WWS95zWuMqYR/fYMRcLDyJuXrCp5hCDiQqx2bZMBDcPlQtNh5Np6iLlVJUXVohVTFkh1jNsK7FaG6J+y8P9rRATEZbWVrLLa5k4TYXScGGFmBvj2ccsJpMzdAZahk5XIVYfLae2MuyHkme60MreV9g/xiPJzEQgVrC/5XURtveOMDaeZXm9fX5bGqIk0zmGxtIYY8dzXFMttZVhv2Xi2HiWbM4Urab0qi8fce/hU1rr6B5O0hVLTmr76YVfbQMJP8Ctj9qQ03tc565ZbG8zOMbYeIbBsfSk3wHefGnxaeYQq6kI4/0XPhhkRcvLJleIDdk5DotpbYjSN5JiZ9+Izh+mlPJd+O17eOMV6/yfX/mtu/n0ryfa9hVWOnne87OHD/rYFqreWVQzdcUS/OCunRMLpmgVadyKb92xbTZDU0qpQ91VwAXBBcaYNxtjTjfGnA78BrgxsHqHt84Y86HA8iuADwBr3VfePpVSSqlD0Yd+/ij//KvH53sYhwwNxJSawb4Re3KjWIVYU12EcEj8sMs7qd3SEGXvwBjdw0nOcCf1veqS5x69CGPs3EXeXFazOQkdrGQpPNFtWyZm/HnEis2LNJe8sQTDgeb6iN/KsCVQIWaMbSG5qsSKpbzHGQh1RITFNRV+y8Q1S2sA2NhuA61iFWKjLvRoHxyjpSE6aS6r1oYoiXSWspAUrWSqKAsRkolALNh+zjvGve5K+QMKxBqraCusEHMVZx1DCUTs46lz86sV6orZSqxgyLK/c4iBPYYJd2W2NzdVkPeYhydViCUJCTzXVXjtGRhlOJEhkc5OO2+ciJ3PymuFdebqiUCsLlLuh0LDyYwfZDUXvPaX10fY5IWi7jn0QrOOoQRDY2nXxjNKS0PUb6XoHcfaYoFYnb2Pp7viNFaVs3pJtW3LGEtOas25MvBeDr5eVy6qIpXJUREOccZR9rjs7Z+YZ7CwStSbO89rmVhsDrFQSPwKzdbAXGpVFeG81lq5nJm+Qsyfu200b042pdSRzZuf0+MFYEfSpfTdgfknY0UqsgtNM+3ZlGIltn8MtnFf6kcAACAASURBVCCeK7mc4Wu3bJ5VkPdMmW4uOaXUkcMYczcwUGydq/L6e+CX0+1DRJqBOmPMA8a2jrgGuHiux6qUUkqphU0DMaVm4AUcxQKxspD41Sf10XL/ZHqrO9GezRlOX9VAOCR+5dJZR9uT4W0DY/7J+KkqN6ZTXhYiUm7fwoUn05/JlokQCMQCj8MLlMIh8Y/dqkCbxNVLSg3E7NgrwqFJVXqLayroiiWIJzOc3FoH2FZE9dHySXMlefsZSWZstUyRcMCrsilsQekREaLlZRMVYhXBQCy/ZWJkli0TwYZX7YMJcjlD3M1rFfXnEEtQHy0nFBJqI2HGs7m8dkKjqQzxZIbl9VE/AKmNzG5eqMIKukJTzyFm5zA7ZqmtAtzTb8NhmDy3WyGvwqouEmbVoioqwvZ5qIuG/QBuJGUrxOoi4UnjaqqL+CGe9xr0nteu2MS8fq0NUVoaIn7LxIn3SpHgLxomWl5GNmdoaYjSXB+hN56iJ56aFPC1Nkb9qq38cCzq/+u1C20bHAu078x/PdZUhhlJphmZpkIMir/3qirL8lom9o2mGM/kpqxEDbYO1ZaJSh1+jDFs6Y7PfMP93u+c73LBOfvLE/N03bypG4CfP7BnytsHL0YoVaLEloCZ7Nwf8Id3D/D9O3fwL4HKv4VCm5gppfbDC4EeY0ywhPZoEXlMRO4SkRe6Za1AsJ9Uu1umlFJKqQJmVpf7HRo0EFNqBt78VMtqi5/I9050B082B6s1VjZW0VQXIZWxodnxTbVAwcnwWbYp8+ZUWlHQDq8uUu5aJtqT/AezZaIdh1elMvE4vKCgqS7itzM8KlAVdlSJLRO9EGRFkYquxdWVbOm2c0yc0lIP2EqfprrJ4aVXYRNPpWkfTBQNB7znbbrnI1pRxribEyu/ZWLBHGIHUCG2ylUTtQ2Okc4aaiNhqv05xJI0uOdzokJrIpDygqfl9ZX+Y1zZWMVs2uMHX/PVRQKxSHmIcEiKzCGWpLk+yvK6CBXhEG0DY37wNF2FGEy8n1oaorZirMEL9fLnEOuKFZ/vKrh/fw4x97x2DiXyArHmhqhfaeaFesUqxETE329Lg31cmZwhmzMsr88fQ2W4zG/XmVch5s0n1ljF4uoKqirK2BsIxQsfS01lmJHURIVYsUAyON7g9lUV+S0TO6YI3TzBcHg27VuVUgvbbx7t4JXfunvO5vY60oOKp7qGp1z3gWvWT7ttLJFmPJOb9jZT/cfTCyDn8vBn3U5TOk+XUurQ9lbyq8O6gFXGmGcDnwR+ISJ1+7tTEfmgiKwXkfX79u2bo6EqpZRSC5scAT1BNBBTagZehVhhCz7PisC8YZ7g9y0NUX/epOb6CE11EcrLhLYBe3J+UXUFVUXa0ZXCC0QmzSEWDTOcSAdaJh7sCjG7/2AY4QUFwWWLqiuorbTzHhWr0Cq+7+KPEWBxdQV9LrBctajKv22xKiRvXZ9rsVgYIsJEqDBdxV6w8ixSbA6x4QOfQ2yFCw6f7LQn3eoi5f7++kfHqa+qsMujXkA0EX547Z2W10X9YzybdokwUSFWEQ75lVpBIuLmMSucQyxBc32EUEhY2Ri1FWLeuGYMxOxj9143E4FY/hxiHUPJouFNsNWld19LqiupKAu5ef28AMq2lBwYHSeZzvrz7U3VXtR7TbU2RPNeX8Vaa3rHO3jcvcq3lYts0LdqkW2L2TmUIBySSa/ZGjc/XDyVQaR4y0rvuNhxTd0y0Q8Bp3jPea1fvcenlDq8POX+luzoHZmT/XkV74fzFYMHy2n/dRvv/OlDs9rW+7wzl7z/7C7kZ3Ihj00pNf9EJAy8AfiVt8wYkzLG9LvvHwF2AMcBHcCKwOYr3LKijDE/NMacaYw5c+nSpQdj+EoppZSaBwctEBORr4vIZhHZKCK/FZEGt3y1iCREZIP7ujKwzRkisklEtovI5TKbkgal5lhvPEllOFR0Dh+YOIG/oiAE87S6Fmve8rKQrXppGxyjY4pKpVJ5J8MLw6X6aDk5Yyt1oHgbuLk0MYfY5AqxYCs3EWHV4ipa6qNUhksLjLywbWWROccW11T43y+trfRDhWLVfN5+trq2UcWOu/e8TVsh5oKpinDIr3wDW5VTFpKJCrEDaZnoXlN/3dzrxj4xhxjgV4h5x71oIFYf8R/HyiLhXym84znVax9sKOfd/2N7B0mMZ/0KMYCjl1TzRGfMD6KmqrT0eG0GvdeN9zwF5xCLJ23LxOYi8115IViwbWYoJCyvj9AZS9I5lKAyHGJRdYX/Gu0cSvhVdsUqxIDAeziSF+oVq3hb2Vg1aR46Lxzz5s5b0VjFlp44mzqGWV4fyXstgT3mXoVYTUV4UnWkfzt3TCZViAUDsRkqUctC4h/L2VarKqUOTbmc4aLv3stfnuopeZu3/PCBgzgidfOmbn8e0aCMm8PNCzjnwkL+n9YCHppSamE5H9hsjPFbIYrIUhEpc98fA6wFdhpjuoBhETnbnWt6J3DTfAxaKaWUUvPnYFaI3Q6cYox5FrAV+LfAuh3GmNPd14cCy68APoD9wLIWuOAgjk+pkuyLp1hWVzlly7niLRPt94urK4hWlE3MTeVOnq9cVMVtT3Zz19Z9rF5SWuvAYmoittqquaBtm1cR1jYwRqQ89P/Zu/PwuMqyf+DfJ3vaJt2B0lJaoezIYikoIiCgoCiIqIAiuCGivr76/tSiIiirQCn7WqAUkAItUOhG971Nm+5JumRt9n2dJLM/vz/mnMlMcmafM+fM5Pu5rl7NnPOcc+4kk0nmuc99P2Enn6I1MCk/tDrnxEEJgx9ddBJuu3hqxOfWSuqMHzVQtTchL9ubgNBsmaic55N9npsAg60hFixJqSamRgxKeAkhMCo7Iz4VYmNzkZ2RhkW7Pe/rjs/P8WtZOGaEmhDz/N/d70Cf3YkNR5pR0eqpADghPweTRufiqjOOw9fPPC6qOCYqX0etdomqPKWSqc1iw00vbcPtrxegz+7yPhdu/tIU1Hb04787azBhVLZmpZn/5+75PqvPm/NOGoMTR+dgRFY6RilVUsX1Xejqd2i2TFSfd4Mrt04ck4Oa9j4caujBZKUdo+/aYt1KUi9Q8vgE35aJGm0Zfd128VT89drT/dahO/2EfGSmC5wz2dPa84KpY1DT3o9NR1s0n9vq19VicwRcP8wzLhPpacK/vWVWBvrsTrT32vHYisP4785q5OVkBK0UnTwmFxmDzkNEqa/X7sT+2i787/v7Ij52OKwhZpRn15YG3FfR2jtkW3uvHeUt0VcA7qxsh8MVvJVjolW1DU0KEtHwJYR4D8B2AKcLIWqFEL9Qdt0C/3aJAPA1AAeEEPsALAJwt5SyXdl3D4B5AMrgqRxboXvwREQRcrklps1ehrmrjxodClFK0q1sREq5yufhDgA3BxsvhJgEIF9KuUN5vADAjeAfKGSw5h4bJo7SbpcIACeP90xmT/WpYMrLyUReToZ3wn3SoOTQVWcchzaLHd8570T86KKToo5tdG4mjs/LGZJkUFvp1XT0694uEdBex0hNKg1OPP30y9MiOveUsSNw+vF5uOQL44bsGzdyoEJs/Mgsnwqxod+vyUqSaVt5G/KyMzBDWcvN1xenjMbdl5+Cb5x9QsB41KojrYRXXk6Gd124nBgSYjmZ6Vj6+6+ipceGvJxMnDM5Hz0+a0JpVYi9v6sG//qsxLN/RKa3Qu31Oy+KOg716xg0IZadie5+z7psUgKFxzoADCSQvnHWCThrUj5KGrpxrpIMCuYLE0fiq6dOwGUzPG1Jbp11Em6ddRKEEBDCs5bWJ/vqkZOZhstOHdq6RH0OHD96cEIsFx/t8SRDf/21L3i2KYnkuo5+b9vHQD8vvlWeE0ZmIyPNE894n+egaua0cZg5zf/5OnlMLvb+8xvetcDuueIUfPvcSdh9rANnThq6pMGoHE+FWI/VGXD9MAA4Z3I+WnpsfhVmuVnp6Le78P6uGry8sRznnzQGv/zq9IDnAICzJo1Gd79zSKUaEaWOh5Ydwv7aLjx36wVGh0I+em3O0IMUDy0t0dx+4YOrAQD/c9UMXHPm8Th3Sujft4B/FVZpkwVnnRjxEju68E3uSWZeiQiAlPLWANvv1Ni2GMDiAOMLAZwT1+CIKGGONvXgG3M3YdOfr8TU8dF1wkkG6o1KL28sxx+vOc3gaIhSj7591Ab8HD49nQFMF0LsBdAN4B9Sys0AJgOo9RlTq2wjMlRLjw2nTBwVcP+FU8fi5Z9ciK+f4V+Fc9akfG+ybJJ3PS3P/3deOh13Xhp8gjocv73yVLT0DF1TYrSSMKnr6MOYEUMn7OPtwqljcNG0sX7JgZPGjcDLP/kSLpsxIaZzj8rOwOd//JrmvglKy8S8nAzkZKbjhNGeBI5W1c6EUdnY989vwOl2IyczHZnpQyuVMtPTMPu6M4LGoyaatBNimQD6/cZFa8bxeX5JuxE+1/OuIZajriHmwLG2PuRmpuPGCyZrtvGLRjgtE/NyMnCsrQ8NXZ7P+1vnnoDlBxu9PzNpaQJ/vOY0/GpBoeb3ZbCczHS888uLvY8HV2b++OKpsLvc+M0Vp2hWM+XnZGBUdsaQysQvnTwWG4+04B/Xn4kbz/f8ajlhdA7SBFDb2Q+7042s9DRkB6hgu/y04/Dtc9tx5gn5SEsTOC4vG2lpImArQy2+iS0hBKZNGBmwQnRUdiZcbolWiy1ohdhdXzsFd33tFL9tI7PS0Wt3oai+C1PG5uKT314aMra/Xnc6HC5OOhKlus/21yM3Mw2P33ye33bfpMNP39iJC04aE/JcNqe5KoqS1YNLD4U9dt6WyqD7n11bimfXlqLikW8N+f1ksQ29wcL3d6yZ1oTT+tuWiIiIzEFKiU/31+Nb507SnFfR04eFNQCAlcUNQ94HExGFK6aEmBBiDQCtUoq/SymXKGP+DsAJ4F1lXwOAqVLKNiHElwB8IoQ4O8Lr3gXgLgCYOjX81mtE0WjuseHLp4wPuF8IgWvPmTRk+5s/uwhpykTDuVNG44T8HJwXxgRTJM4+UfsOYDVR0mqx4+Tx0bdkDNe150zS/Bpce07gSqt4GD/SkwCbmOefCDsuQOLFk6SKLVGlJsK0KsDyfBIXOSFaA0YqIz0NWRlpsDvdQyrEuq0ONHT1Y/LYXDx607lxu+a4EVnISBMYmR34a5aXk4keqwN1nZ5WkQ/deC7+8e2z/KoFrz7zOFz/xUm49NTYkqMAcO+3zgy6XwiB5267ANMHPe9/fPHJ+PHFJ/tty8pIwwn5Oajt8CQT83IyArZGnTp+BF748YXex1PGjUC6jouvqEmwhi4rpkfYVjU3KwP9dhdK6rtxdph3+2dnpCNI3pOIkshDS0tw6akTcOUZ2u1yPyisxeM3nweXW3rXA3NL4K1tVfjRRSdh09EWbDraksiQhzW7RqvClcWNMZ2z3+Hyq+5efrAB97y7B5/97qt+44L9GvvF/F24ddZUXH3W8THFQkRERKllZVEj/rBwHypbe/G/V6du9dLKokbkZqXj8tOGdqYh85BSorTZgtM0ukARBRLTjK2U8mop5Tka/9Rk2J0ArgfwY6nceiqltEkp25SPd8PTt/k0AHUApvicfoqyTeu6r0opZ0opZ06cyBcm0o/N6UJXvyNoy8RARmRleJMmk8fkYsffrsKpxwWuNIsn33WQ8oNUlyS78UqF2ATl+/OVU8bjki+Mw+kn6PeLUE2IaVWAqYnIrPQ0v/Wj4kVdt0xdQ2xklmcNuR6rEw1d1rhVhqnS0gSOz8/xVhxqUde6aujsR3ZGGsaOyByytpcQAs/fdiFunZWYGxiuPP24sNfmmzJ2BGo7+tFtdXpbjYbjiZu/iP98/4vRhhiSWpXX1G31S7SGY0RWOuwuNypbewMmzYkodc3bUomfzd8Vclx3vwPF9d0APAmU+z8txhn3rdQ7PApDjzX8NorhUBOcRfVdAccM7ky49nAzfrmgMOJr/fnD/Zj50OqIjwsknnVrpU09mDZ7GdYfbo7jWYmIiIaX9j47AKCp27wV3fG4dfXud3bjjjd2xuFMpKfFe+rwjbmbsP4I/76j8OlW2yqEuBbAXwB8V0rZ57N9ohAiXfn4CwBmAKiQUjYA6BZCXCI8t+j/FMASveIjCofasuW4/MgTYkbyTWBEMsmfbLwVYkpC7NTj8rDwri8HXXMpVjlBWiaqycecTH1eWtW2iWpCLC1NIC/bk5Cq77R618SKp7k/Oh+/v2pGwP35uZmw2J2o6+zH5DG5ASuszGrK2FzvGmKRJI9PHj9S157lahLM4ZIRP59H+CRrw60QI6LktL+mE1c+uQEWjXWojrX1oqiuC2/vqBqyr6a9D7+KItlByaOzz47Sph4AwMJdNZpj9PiN/eHuWrRa7DqcOXZ7qj3rnK4oasD6w83Yrax7SkRERETJqUS5wa+82RJiJNEAPZu9Pg8gD8BqIcQ+IcTLyvavATgghNgHYBGAu6WU7cq+ewDMA1AGT+XYCh3jIwqpvdfzhn7cyORKiPlOoAer7kl2uVnpGDcyC1PGxj8RFPCaYbRMjHX9sEBGKN/X0bkDa7Xl5WSi1WJDq8WGSWPiWyEGALOmjwu6hl5+TgakBEqbLbpcX2+Tx+aioasf7b12ZQ04c/D9GR6VHVlcI7IGjmWFGFFqe+LzI6hs7cXe6qET+5c/sQHXP7dFc33AW17dgUImA1JWbUc/zv/3alwzd1PAMV39jqAtE+Np/eFm1LT3hR4Yo41HWzBt9jLM3xp8rTUA+Nn8Xfj+S9t0j4mIiIiIiMxFt4SYlPJUKeVJUsrzlX93K9sXSynPVrZdKKX8zOeYQqXl4ilSyt+pbRaJjGJ1eNZ1GKFTgkMvGelp3gn1fBNN8uvhg19fgnuuPDVh11OfC1rPCTWholU9Fs9rqxVinmtmoEy5E0aPCrFQ1CRgZWsvJhlw/VhNGZsLtwTKmi1+rUaNNsqnWm1UhC0T1TXfxo/MwvFJVt1KRIlR19lvdAiko28+HTgRpjrvX6vgWyMmJbC3ugPTZi/DgdrOuMThdkusKWnCz+bvwtVPbYzLOQez2Jx4fOVh2J1uzNtcAQB44LMSXa5FRERERETJT88KMaKkZ3W4AADZGcn3o6JWhqVyhRjgaZOYyM9RrQzTSnrleVsm6pMQU685ZlBLzPIWT0LMiAotNQnocssha4clgyljPW0P++wu5EVYiaUn31jyImyZqD5PzjoxP+laWBIRUXw5XW7vx/d+dDDgOAmJdcraWn/6YL93+7G2Xu/fw4Dn9/2cVUfQ1ecYOFZKSCmx+1g7fL1bcMy7DpnN6UY0Qt0e+fTqo3hxQzle3lge1fmJiIiIEu2z/fXYEMaaVzanG4cauhMQEdFQqVymlHyz/EQJpL551yvBoSc1OWOmqpdUoCYbtNoieivEdKooHOltmeiTEMvJ8LbDMqJCK8+neunE0cnXMtG33aaZflZ8q8LyIq4Q84xnu0Si1LP+cLN3XSiicPzm3T0B9wVqGVjmswbD5U9swK/f3u19vOZQE55bV4YHPisG4KkCm37vcky/dzm+/9J277jCqnbUdVqHnPuF9WWYNnuZX5ItmMYu/3P84OVt+GhPrfex+rf6U6uPYnNpa1jnJCIiIjLS79/bizvf3BXW2Oue2axzNJTq6jv7caytN+zxw+G+aibEiIJI5gqxfCVpkuotExNNTXYFXUNMrwqxrHTkZWcgI33g+ei77tWJBlaIAcCkJKwQmzQ61/vL3rRriEWYEFMTpl+cwoQYUar52fxduGbuJlzw71UorGoPfQANe6tLmsIaF+wO0I1HW7wfq2+m1b+RWy02zWNufnm75vY3lfW9eqxO/PH9fViyr27ImJ/PH5gg+snrBX77dlV1+FWwERER0fCRyhUrRHr5ymPrcPkTG4wOw1SSb5afKIGSuUJsuLRMTLTcMFom6pUQmz5+JE49fpTmNUfnZmJEVuIrnPJ9kjWTDUjIxSorIw3H53nizo8w8aSnrIw0byJ+VIQtE88+MR9v3DkT3zz7BD1CIyIT6Ohz4OaXt8dtrSeicD2y/LD346NNPWjrtYd97OLdtWi1DIz/eG8d/rBw35BxffbQ1WMf7KoJ+7qDhZpMa7XY8Pb2qqjPT0RERPoSGAYlLESkG/PM/hGZUFJXiCnVLvlMiMWVdw2xrKHPCfVrnaNTy8Q/XXMa/vfqGf7XVL7PkwxqV+hXIWZAy8Z4mDI2F43dVlNViAGeZKfNYo+4ZaIQAl8/43idoiIiM+m2Oo0OgVJEpDdcSwl8Y+4mv21CBE82/d+HoSu79lZ3hHX9ZQcb8MOLTgprrEpr8qzP7hxyQ9Fv392Dgsp2fPmUCTj1uFFDjiEiIiIiouSVfLP8RAmkVohlJ2GFmLoeElsmxpfaMlGrCixf5wqxtDTh1y4RGKgQO9GgdoXetepyMrxrVyUbdR0xsyWP1cqwUdnmiouIjBGoNZ1q2uxlmDZ7WYKioVQjpQx6r/W8zRUJiWNbeVtCrqO68w3/9Tuauq0oqPS0I3W63QmNhYiIiIiI9MeEGFEQyVwhxpaJ+hihJsQ02hOqFUZ6JcS05BlcIZaTmY6s9DTDEnLxMGXsCACIuBJLb+raYZGuIUZEqWlLaWvAfe/sOJbASCgVfe/FbUH3P7TsUMTnjGZB7ic+PxL5QTHYOWgtvvIWS0KvT0REREREicVZNqIgvBViSZgQ++bZJ6DX5vRWilF8hLWGmE4tE7Wo318jE1J5ORlJnhBTKsRMVk2Zp1SGRbqGGBENP58XNxkdAqWAw409QfcXVAxUb0mNJosC/q0Xt8e52mtnZXvoQQnickss3FWNH848CZnpyfc+gYiIiIhouOIsG1EQNocL2RlpENHc4mqwMyfl4+/fPsvoMFLOmZPyMfu6M3DF6ROH7MvNTMe08SNwysSRCYvH6AoxAPjeBZNxxqR8w64fq+vOmYSWHhtOPyHP6FD8eCvEmBAjGrasDhcW76nFbbOmRlVtQxSJVSXBE6uFx4Kv7+UelCPbV9MZ9rXvX1LkXadVy46KNtzy6o6wz6e393ZW4x+fFMFideLXl59idDhERETDijvYoqU0rPA9EkWDs2xEQdic7qBvzmn4SU8TuDvAxIcQAhv+fGVC45lx3CickJ+D804ak9Dr+vrH9cmdeB09IhO/v2qG0WEMkZedgRFZ6UhP4194RMNNdVsfdla142hTD17dVIGxI7KMDokILp+MV7znod7aHrztZ1O31e9xLJMf8Qi9q98BAOhU/iciIqLEeXTFYd6QQkRRY38HoiCsSoUYkVmdOCYXO/52FU6ZOMroUCjOzjtpDGZOG2d0GERkgBte2IL/9+F+tFnsAID9NZ2w2JwGR0XD3VOrj3o/DlVNZkoBkmjzNlf4DOFNKERERGbFujDz2VPdgeL6LqPDIIoIZ/qJgrA6XKwQIyJD3PGVaVjw81lGh0EmIoT4oxCiWAhRJIR4TwiRI4SYLoQoEEKUCSHeF0KwlCiJrT/cjL8s2o+OPv+qk1c2VeDvHxcZFBWRvvrtrrifU2qVsAWYRXtk+SHN7dc+vVmX2IiIiCg6oSrU2Ukx8W56cRu+/ewWo8OgMHRF2NkglX+cmBAjCsLmdLNCjIiIDCeEmAzgfwDMlFKeAyAdwC0A/gNgrpTyVAAdAH5hXJQUq5/N34UPCmu9jytbLQZGQ5QYc1Ydifs5VxQ1Ymdlu+a+SGrAeqxsiUhERJRsErWuVI/Vge4w/1Z4dm0pfvrGTp0j8jhQG/46rjR8nPevVUaHYBqc6ScKghViRERkIhkAcoUQGQBGAGgA8HUAi5T9bwG40aDYSAd7qvlmllLf1vK2iI8JNc91z7t78MNXtnsfl7dY8JfFB0Kfd9CJ//f9fQCAvdUdKGvuiTRMIiIiSmHnPrAKX3wgvCTDU6uPYtPRFp0j8vju81sTch2iZMWEGFEQNqcbOZn8MSEiImNJKesAPAmgGp5EWBeA3QA6pZTq4lK1ACYbEyHFKty7S4lSwc/mD9whXd6sfyXki+vLA+4TQW4j36Yk67734jZc/dSmuMdFRERERESJxZl+oiCsDheyM1ghRkRExhJCjAVwA4DpAE4EMBLAtREcf5cQolAIUdjSkpg7Eyl8Hb12/HJ+odFhECVMUV13ROMHr+XVarGjudsa9vFby1q9H6fyeghERERERBQcE2JEQbBCjIiITOJqAJVSyhYppQPARwAuBTBGaaEIAFMA1GkdLKV8VUo5U0o5c+LEiYmJmMJ2wYOrsbNKe70jouHuW89sxuyPDvptO1jXhVmPrMXbO47F9VpatWLH2noDjpfMrhElhBDiDSFEsxCiyGfbA0KIOiHEPuXft3z23SuEKBNCHBFCfNNn+7XKtjIhxOxEfx5ERERkPM70EwXBCjEiIjKJagCXCCFGCE9/r6sAlABYD+BmZcwdAJYYFB9FQEoJt5sz6UThKGmIrJrM17TZy+B2yyFrg/kKtR7Z5U9sGHqMz0EvbijDGfetiCo+IgrbfGhXxs+VUp6v/FsOAEKIswDcAuBs5ZgXhRDpQoh0AC8AuA7AWQBuVcYSESWF+VsrsbqkyegwTIk3KVEkmBAjCsLmdCObFWJERGQwKWUBgEUA9gA4CM/fcK8C+CuAPwkhygCMB/C6YUFS2B5adghf+Nty2Jwu/Hz+LqPDIUpprkEzJB29dr/HzgiS0+UtnvXOfE/5+MojsDrc0QcYoW6rwxtHIvxkXgFuf70gYdcj0iKl3AQg3FLqGwAslFLapJSVAMoAzFL+lUkpK6SUdgALlbFEZAK7j3XgmTWlQcfIYd74+IHPSvCrBWyz7ivUjU1EWjjTTxSE1eFmhRgREZmClPJ+KeUZUspzpJS3KxM9FVLKWVLKU6WUP5BS2oyOk0J7c2slAOBQQw/WHW42OBqi1Oc7WbI2hp+5knr/arWXezFdggAAIABJREFUN5ZHfa7mHiumzV6Gdwsia/v4g5e246o5G6O+bqS2lLVic2lr6IFExvidEOKA0lJxrLJtMoAanzG1yrZA24nIBL7/0jbMXXPU6DBMgdVORPpiQowoCJvTxTXEiIiIKK7UghSHK3FVJUQUmgjWWxFAV78Dt722Ay09sd97sEVJMv3946IQIz3uWlCID3bV4EhTT8zXJkoRLwE4BcD5ABoAzInnyYUQdwkhCoUQhS0tLfE8NRERkWFKm3rgHObvQznTTxSEjRViREREpJM/fbDP6BCIhoVQia5w/eOTImwrb8P8bVVxOZ+WlUWN+PdnJQCA218vwF1Ka6RVJU34y+IDul2XKNlIKZuklC4ppRvAa/C0RASAOgAn+QydomwLtD3Q+V+VUs6UUs6cOHFifIMnIjKxqtZePLriECRL1VJOZWsvrpm7CU98fiSu5/1/H+7Hp/vr43pOPWUYHQCRWbndEnaXmxViREREpIua9n6jQyAynH0Y3aG6sqgBW8paccVpxwVsh3T3O7sBAP/8zllsVUgUhBBikpSyQXn4PQBqueWnAP4rhHgKwIkAZgDYCU/31BlCiOnwJMJuAXBbYqMmIjK/X7y1C+UtvbjloqmYPmGk0eFQHKldDvZUd8T1vIt212LR7lp897wT43pevTAhRhSAzel5c84KMSIiIiKi5FXXaY7k893v7AEAvLOjGnN+cJ7B0Qwob7EgJzMdk8fkBhzT1G1Ffk4mcrPi896ovdeOPcc6cPVZx8flfJTahBDvAbgCwAQhRC2A+wFcIYQ4H4AEUAXg1wAgpSwWQnwAoASAE8BvpZQu5Ty/A/A5gHQAb0gpixP8qRARmZ5T6e8en/p6SlopXCCoW+mLEOIBIUSdEGKf8u9bPvvuFUKUCSGOCCG+6bP9WmVbmRBitl6xEYXD6nABACvEiIiIKG62lbPigyiRwu32U9naiwXbq6K+TrfVEdH4//twf9TXirer5mzEpY+tCzrm4kfW4rZ5O7DsQAOmzV6GXpszpmv+7M2d+OWCQvRE+HWj4UlKeauUcpKUMlNKOUVK+bqU8nYp5blSyi9KKb/rUy0GKeXDUspTpJSnSylX+GxfLqU8Tdn3sDGfDRElks3pwuVPrMemo8HXAnS5JR5dcQhtltjXCSXj1Hb04dZXd0T8dxkNiFOncVPTe6Z/rpTyfOXfcgAQQpwFT2n62QCuBfCiECJdCJEO4AUA1wE4C8CtylgiQ7BCjIiIiGJlsTnx0oZyuN0S6w8347bXCowOiWhYkWHc3tpqseHKJzdg6YGGkGMD+fWC3VEfmyz2Vnfi6TVHAcRedVfV1gfAMwFJRETDl83p0vX8Ne39ONbWhwc+C14QuuFIM17ZWIH7lhQFHUfm9syaUmyvaMPKg41Gh0ImZkTpyw0AFkopbVLKSgBl8Cx+OgtAmZSyQkppB7BQGUtkCFaIERERUaweWlqC/6w8jNWHmvCz+buMDodo2Dn9HytDjunuj/0u4kON3UH3F9V1Bdy3qrgRx9p68ejyQzHHkQwW7a5Fl/I1/+viA6hWkmNERDT8/OmD8Cumw636jobaJtDh4o0aRKlO75n+3wkhDggh3hBCjFW2TQZQ4zOmVtkWaDuRIVghRkRERLFauMvz5+2v30796hGiZFXV1hvzOdRJujUlTfinxt3l1z+3JeCxd729G5c/sQGvbKrwOZ+5J+QiDc/pcmNbmadl7P/zaRf5eXGT32MiIhpe1pQ0hT22uceqYyTxVd/ZD0uM7YUp+dmdbpxx3wp8srfO6FAAAEv2mSMOo8WUEBNCrBFCFGn8uwHASwBOAXA+gAYAc+IQr3rdu4QQhUKIwpaW4D1giaLFCjEiIiIiotT38/mFMZ+jq9+Blh4bfrmgEAu2HwMAPPn5ETy7tjSq8331P+tjjkkP0a4rMXfNUdw2rwC7qtrjG1CM2iw2fFBYE3ogEREZbnmINnjhtElOlK88tg7fe2Gr0WEMG2b63vvq6LPD6nDjEZN0AXi3oNroEEwhI5aDpZRXhzNOCPEagKXKwzoAJ/nsnqJsQ5Dtg6/7KoBXAWDmzJnmfMZT0mOFGBERERERheuih9d4P542e5n34/+5akbE54pkjS4pJf71WQl+cslUnHpcXsTXipWUEocaenDWifkBx5Q3e6rwWntsQ4+PYBKro9eOkdkZyMqIz02L97y7BwWV7bhk+nhMHT8iLuckIiJjCUR590aclTZbojou2ptPhiN+rSgaupW+CCEm+Tz8HgC1b8SnAG4RQmQLIaYDmAFgJ4BdAGYIIaYLIbIA3KKMJTIEK8SIiIgoXDXtfahp918H56GlJQZFQ0RmcvY/Q69jFovq9j7M31YVl0q3cD2y/BD+ssjT6nD+tip869nN2FHRpsu1vjl3Ey5+xJNsvODB1bjn3eha0FpsTu/aZaoWJUHncLtjC5KIiIgoSZi8M7fu9Jzpf1wIcVAIcQDAlQD+CABSymIAHwAoAbASwG+llC4ppRPA7wB8DuAQgA+UsUSGUCvEcjJZIUZERETBXfb4elz2uH+Ls3lbKg2KhojMpNfuSsh1qtv78PU5G6I+/r8F1XC6wksMbTzagg8KawEAxfXd3uvr4UhTD5q6ByrL1hxqBgC8srHcrxIvlC89uBrn/WtV3OMjIiIKV1N35Oug/c97eyOqHCei4GJqmRiMlPL2IPseBvCwxvblAJbrFRNRJNQKsew4teMgIiKi1Pf29irc/uVppukTT0TDS0VLb8gxLrdEr92J/JxMv+1/+/gg1h1uxrw7ZqKp24qLH1k75FitNlSR3GWsNTTau5QfXXE4ovHqDY9ERERGmb34QMTHfLq/HvZh8Dus1WJDVWsvZk4bZ3QolOI4008UACvEiIiIKFL3LSnGp/vr8eqmCqNDIaIUsa2sVXP75tIWFNd3hXWOpm4r2nvtAICHlx3CFx9YhT67c8i4NYeaMG9zBQqrOsI6r/TJZgVbxsPsa3wM99ZBRESxsticeHt7ld/vBRrKxS9PQDc8vxU3v7zd6DBoGNCtQowo2bFCjIiIiEKxOV14YV2Z37aXNpQbFA0RpaLb5hVobr/99Z0AgI1/vmLIvvIWCyaMzMboEZ4qMLXaa1R2hneN5F6bCyOyhk4JPLTsEF647cKwYluw/VhY40wrgkRdTXsfVpU04Rdfna5fPERESeqBT4uxaHctpk8Yha/OmBD2ccwPkSrZ2kJKKVFc341zJo82OhRdyBT+6eRMP1EA3oQYK8SIiIgogDe2VOHZQQmxQw3dBkVDRMOR1s34V83ZiO88v2XIdottaFVYJAZXen20ty7mCRMzTLeEU9Hwk9cL8ODSEm+lHRERDehQXhvVuTTTCfEyn6jCtkBV34CnpfHe6vAqtPXEIr/wvL6lEtc/twU7KtqMDiWutNpjpxomxIgCUFsmskKMiIiIAuk365t+Iho21h9p1txe3d4X9DgJibd3aFd4tffaNLcHW4dL+GTLiuu7cLhx6M0BWpNssbbXemZNaUzHA8A1czeFHNNj9SQT3ZwpJCJKCtvL2/BdjZtDgoklFXD327vx+pbKoGOc7sC/Q55ZcxTfe3Eb9td0xhBF/Ji93bHRSpSbIGs7kquyjZgQIwrIxpaJRERERERkcv/6rMTvcWOXNcQRAzNc7wRoeXjfkmLN7Zp3/mvM7X372S249unNA1eMYFKto9ceUYXB3DVH0W11hH8BeCp5H1paElF5GucFiYiSy98/Pog+u//vk4KKNvz23T1h34xxwwtb0W8P73fSyuJGPLi0JPTAANQES3OP9k0pRBQfnOknCsDmdCM7I83vTkciIiIiX1tKW4wOgYiGoQsfXB1w3yWPrg16bKtlYKIt0rc6oYY/vvIwiuu7vI+tDhd+PG8Hlh9sDHjM4CnJCx5cjZtf3hZZYEFYHa4hk5m3vrYD87ZUorM/skQawFZSRETJ7Ofzd2HZwQb0hpnk2l/Tif215qjYosD4u5kiMXQFXSIC4HnjlMP1w4iIiCgAq8OFPdV8g0xEiWfUOlb1QarPLFYHXtxQjhc3lHu3/e3jg9haNrC2htZ6Yy63xLbyVnzllAnebUV18VuLceZDawKunRZJPpD3SRIRkVFiXa8zVbGIITrD/dnECjGiANQKMSIiIiItZ9y30ugQiIiCeuBT7daHADDr4bU43NgT0/n313R6J1U+2Vc/ZH9Zs8Xv8bs7qoeMOVDbhdteK8DOyvao43hk2aGA+7SSYbHcSc5JSSKi5GN3uWNes5KIUgNn+4kCYIUYEREREREls/nbqhJ2rX01oStmt1e0BdzXEsOaKQt31UR1XFtElXa8C52IKBQjUk7lLRY09wRfP7O2ox8vb6xISDxvb69KyHWIKDpsmUgUACvEiIiIiIiIggt2x/2B2q6A+war6egbstaXXmKqEmCBARHREFF3rovDa+pVczYCAEr+/c2g4z7aUxv7xcJw35KB6myrw4UX1pcl5LpEFB7O9hMFwAoxIiIi0nLHGzsxbfYyo8MgIgqL3i2ilh5oiMt5HltxGGf+078VbWdf+BVcv3xrV9hju63aa4qV1HfjUIP2+mVcpoSIiCL11rYqPLcu9RNiDpcbsx5eg2Vx+puASE9MiBEFwAoxIiIi0rLxaIvRIRARhe31LZW6nt/p1i/hdsMLW8Meu+ZQMw7WdmHa7GXYXBrd6/S3nt2M657ZDMDTwvHLj65FaVMPps1e5m3pqH62X5+zAef/e1VU1yEiGi66+h343X/3oKvfYXQohrA63EaHkBCdfQ4099hw/6dFRodCFBJn+4kCYIUYERERERElu4eWHTI6hKhMm70Mx9r6NPfZndoTjAWVnjXK1h/2JMTKWyxRX/8Xb+1CQ5cV18zdpLm/oqUXnX3Dc4KXiChcr2+pxNIDDXhzq743Z2iKqLKX/XBVkl+LiOhdiU/xx4QYUQBWByvEiIiIyN+SfXVGh0BENOy5w5x8UteViUabRbtdI+e9iIhSj/rartUeN9Gv+2b5NSMiyygOO6n+9Unlv3c4208UgM3JCjEiIiICnC43fvPObhyo7cQfFu4zOhwiIgrhja2VcMXYyjEtwGwJ75wnIkpOEqGTTUYkOXqsDjR3W4OOSeXkBADc/npBXM5jti9Tqn/fkhUTYkQBWB1uZGfyR4SIiGi4O9behxVFjfju8+GvZUNERPE1bfayiMY7XNGv21LT3oea9v6oj6f4EkK8IYRoFkIU+Wx7QghxWAhxQAjxsRBijLJ9mhCiXwixT/n3ss8xXxJCHBRClAkhnhVCqxaEiIYDM/3wX/PUJsx6ZK1pkidGxLG5tDW+JzTTNxjalYdkHM72EwVgc7qRncEKMSIiouGOfeGJiMzlphe36Xr+yx5fH3AffyUYYj6AawdtWw3gHCnlFwEcBXCvz75yKeX5yr+7fba/BOBXAGYo/wafk4hixL+bI9c4qDrMLLmTZEri8FkXmeH+c8qEGFEANocLOawQIyIiGrYcLjdufGErtpW3GR0KERH5KGnoNjoESiAp5SYA7YO2rZJSOpWHOwBMCXYOIcQkAPlSyh3SMxO4AMCNesRLNDwNZE8au6woa+7xPAgx8W6PoZqXkpPD5Y65rbEqiXJ2ZCKc7ScKgBViREREw5fLLXHmfSuxr6YT/1xSbHQ4REQUIZtDe5L1s/31mttXlzSFdd7hfU+1af0cwAqfx9OFEHuFEBuFEJcp2yYDqPUZU6tsI6I4u+TRtbj6qU1+24xYm8sMuO7kUDP+vgI3vaRvpbcZrTvchIKKNrjdEtvKWod9lZaRmBAj0uB0uWF3uVkhRkRENExZbE4443TnIhERJUZ950DbqTe2VmqO+f17ezW3/2pBoS4xkb6EEH8H4ATwrrKpAcBUKeUFAP4E4L9CiPwoznuXEKJQCFHY0tISv4CJKGGGZwouOeyv6TQ6hIT7+fxC/OjVHViwvQq3zSvA58WNRoc0bHG2n0hDj9XTeSE/J9PgSIiIiMgIVofL6BCIiChCvkmweLVjGkxKic2lTJCYgRDiTgDXA/ix0gYRUkqblLJN+Xg3gHIApwGog39bxSnKNk1SylellDOllDMnTpyo02dARIk0HCtyatr7jA6BBqlq83xPfG/iocRiQoxIg5oQy8vJMDgSIiIiMsJNLw6/Nh5ERKlE6FgaMH9rlX4np7AIIa4F8BcA35VS9vlsnyiESFc+/gKAGQAqpJQNALqFEJcIIQSAnwJYYkDoRCnN4Ypv0mllUSO2lLbG9ZyR0mp72NXviPt11h5uDhJDdH42f1eUR1Io4bTDbOu1JSCS+BoObT6ZECPS0G31/GLLY4UYERHRsFTX2W90CEREFAO9Kn2HYYGB4YQQ7wHYDuB0IUStEOIXAJ4HkAdgtRBinxDiZWX41wAcEELsA7AIwN1SynZl3z0A5gEog6dyzHfdMaKEq2ztRa/NaXQYcTU4URTrS+bd7+zGT14viPEs8bXucBPO+9cqo8MIC7teGOvbz24xOoSo6XljkdFY/kKkYaBlIn9EiIiIiIiIks1rm7XXEKPkI6W8VWPz6wHGLgawOMC+QgDnxDE0ophc+eQGXDB1DD6+51KjQ4mbQNUlZplcj8dNDQUV7aEHUcoTXKUuaelWISaEeF+5S2efEKJKuTsHQohpQoh+n30v+xzzJSHEQSFEmRDiWaWMnSjhelghRkRENCyVt1gwbfYyo8MgIiKTKm3uMToEIkohe6s7jQ4hZi09NthdbgCAW6f1G+Nt8IxzckRNRPGgW/mLlPJH6sdCiDkAunx2l0spz9c47CUAvwJQAGA5gGvBEnYyANcQIyIiGn6q2/pw1ZyNRodBREQm9vP5hcjNTPc+3lHRhku+MN7AiIiIjHXRw2u8H39e3GRgJLGLd2kG2+ySGYXztEzl567ua4gpVV4/BPBeiHGTAORLKXdIKSWABQBu1Ds+Ii0DFWJMiBEREQ0H6w434WtPrDc6DCIiSgL9PmuyPPH5EQMjISIyF7vTbXQIAfnO7ydqsj+FcwqmksrJG4o/3RNiAC4D0CSlLPXZNl0IsVcIsVEIcZmybTKAWp8xtcq2IYQQdwkhCoUQhS0tLfpETcPaQIUYWyYSEZE5CCHGCCEWCSEOCyEOCSG+LIQYJ4RYLYQoVf4fa3ScyWpzaavRIRARURJK40IPREQBJTJRMfhaWivxDLfFeQZ/TWra+7CtLIXe9yTx95M5POPElBATQqwRQhRp/LvBZ9it8K8OawAwVUp5AYA/AfivECI/kutKKV+VUs6UUs6cOHFiLJ8CkaYemxPZGWnIykhEzpiIiCgszwBYKaU8A8B5AA4BmA1grZRyBoC1ymOKwpFGrglDRESRE8k8G0dElCCJfKVMdNLrg8IayDhm/vSM/4onN+C2eQVBx+iVxHx/V3VMazXXdfZjy+CbGJMwqxTO9/fPH+7HuwXHdI9FSont5W1RP397rA5Ut/XFOSr9xdQPTkp5dbD9QogMADcB+JLPMTYANuXj3UKIcgCnAagDMMXn8CnKNqKE67E6WB1GRESmIYQYDeBrAO4EACmlHYBduQnpCmXYWwA2APhr4iNMfmyzQURE0Rhu1QZERMNdV7/D7/FfFh3AlLG5ul4zXu9VXG7j3vQ8u7YsquOsDhdue20H9lR3AgCqHvv2kDGp9rv4w921+HB3LX588ckxnWd1SfA1/T7eW4c/fbAfT/7gPNz8pSlBx2r53ovbUNZsiTY8w+hd/nI1gMNSSm8rRCHERCFEuvLxFwDMAFAhpWwA0C2EuERZd+ynAJboHB+Rpm6rE/lcP4yIiMxjOoAWAG8qbafnCSFGAjhe+RsKABoBHG9YhElOJuPthUREZLi0VJuFIyKKRSq+JErPjfMPLi2BzenCwl01Q4b02lwaB1I8HGns8SbDolXWbMH1z21Gt9URenAK+dWCwqD7q9v7/P6PVDImwwD9E2K3wL9dIuC5u/mAEGIfgEUA7pZStiv77gEwD0AZgHIAK3SOj0hTj9WJPCbEiIjIPDIAXAjgJaXtdC8GtUeUnj4Hmlkdrr8anMstTb0AOBERmRfzYUREqe/pNaV4fUslPtBIhpH5zV1zFEV13dh4hO+FKcaWiaFIKe/U2LYYwOIA4wsBnKNnTEThYMtEIiIymVoAtVJKteH7IngSYk1CiElSygYhxCQAzVoHSylfBfAqAMycOZOlUINc9p91qO+yGh0GEREloV6b0+gQiIgoHEHeBYVqSeh0eW6eS0TLQTOvTfnLtwqRk5mG52+7MGHX3F7RlrBrRSPSZ0SbxQ4AWH6wAb/46vSIr9dqsWFMbiYy0vWuc0pd/MoRaWCFGBERmYmUshFAjRDidGXTVQBKAHwK4A5l2x1gu+moMBlGRETR2l/bZXQIRESmZba25KESX6z6DW7NoSYsPdAQeqAGGeVCaI+tOBxwX3uvJ7n08Z66qM4djb8uOoClB+qjfq4cbeoBAOw+1hHxsX12J2Y+tAb3LSkOOTbar/dwwIQYkQZPhRgTYkREZCq/B/CuEOIAgPMBPALgMQDXCCFK4Vm79TED4yMiIiIiIhrCiERTsEtGGs/yosbogmBSQleVrb0AgCNKkikR3i+swe/+uzdh1/PVb/esVfd5cejn4/bywJV1w/1pyRl/Ig2eCjG2TCQiIvOQUu4DMFNj11WJjiVVfF7ciF+/vdvoMIiIiIiIyEChKtlaemwJioRSkW8bTJGg7LDNxTWyA2GFGNEgTpcbfXYXK8SIiIhSHJNhRERERGQWbrfE/UuKUN3WZ3QoKamitRf9DlfQMYlevytYFY/R2D5yQFFdFw41dBsdRti6+hx4atXRmM6RykVkTIgRDWJRFkVmhRgREVHqquvsNzoEIiIiIiKvg3VdeGv7Mfz+vT1Gh0IJ0m11hDky+dMTiaiMCtUKMNqv4vXPbcF1z2yO8uj4WXuoOaxx/15agoN1XOM0ECbEiAbpsaoJMVaIERERpapLH1tndAhEREREREMkc+pjcMoj0rWKWnps+OEr29FqMU+LQt9PwR3g84km1dPea9c+l8bJ1vgkQiw2JxburIY04UJQwULSI95AObbBm/VIxS3ZVwcAcCSwNeFfFh8Ia5zVGbwScrhjQoxoEPXujHwmxIiIiIiIiIiIKAE+L240OgTdBKsOem9ntffjBdursLOyHf8tqA443kj/XloSt3N99/ktUR133ydFmP3RQeyq6ohbLLEaju0VHS5Pgq+zL9wqP494fKnMmAxNJkyIUVD1nf3eFoLDxUCFGFsmEhERERERERGRvsqaLXhxQ7nRYRji3o8OGh2CboKlLWo7omvhrlbPWTXWQ/vNO8NrjWTmhaL3qwWFeG5dWdAxu4914HBj7Gunud3SVOvlMSFGQd362g48u7Y07PHtvXY8vKwEdmfiykXjjS0TiYiIUttzEfxtQ0RERESkt347W5xR7FYU+VcZ6lVJVNnaq8t5k1GyVsetLmmCK1APUMX3X9qGa5+Ofu20ihYLDjd2463tVbj1tR2mqYJlQoyCau+1R7To/JayVry2uRJF9cm7cF+P0jKRFWJERESpp7PPjjmrjxodBhERERGR6Ukp8fU5G/DJ3jqjQ4lYsiYqjBZOEu3KJzegs097DbSA5402oGFm2YGGsMc2dllDJrWM0tXvwNfnbMS1T29GlZJAbYggx6AnJsQoKIfLje7+8Huh2pRy3aYuq14h6Y4VYkRERKnJ4XLjSGOP0WEQEREREQVkpjZwbglUtPTiTx/si+p4E30qfkRcVnLyOV+A04X6Xprpez1YsHXfAJhiiZ1Iv3x6VMxFekqtL6vD5cafP9yPmvY+bCtvDes8DV39uOTRtZiz6khkASjHhhJLos3mdGH24gNRH683zvhTUE6XRFckCTGlVWJTt39CzGJzIjsjDZnp5s/BDlSI8ceDiIgolTy87BDmb6syOgwiIiIiopRkZFWWiXNLuipvseDml7Zh+R8uMzqUoIws2AuV3DPSHW/sxMajLQCAhi4rTh4/IuQxXf0OtPR41pLbXBpeAs1XU7ct4mMi8V5B9ZD2nQCwsrgR1507Ccfn5+h6/VDMn50YhqSUeHzlYcP7sbrdEk53ZAkxde2wxkE/WN95bgueWZMc63X0WJ3IykhDdka60aEQERFRHDhdbjy1+ijWHW42OhQiIiIiopTlW3mlzhFGIh4FPNGkPsxcqTXY4Fjf2XEMHX0OLD9ojvWZjPLOjmOQBqZFK1t7MW32Mmw40oya9j5878WtYR2nJsOA8Kuy4t0l8dm1pdhT3RFynJQyrCo7u0v7Z39HRTt+9Mr2iOOLNybETKijz4EXN5RjTUmToXE43J4nbzQVYs2DKsSauq3YXBZ5xtoI3VYn8lkdRkRElDKWHmjAs2tLUd3eZ3QoREREFAUhxBtCiGYhRJHPtnFCiNVCiFLl/7HKdiGEeFYIUSaEOCCEuNDnmDuU8aVCiDuM+FyIzMbllmjusaLbGv78XyC+CYntFW0xny/hzFtINITeRU+hkh+xJhFdbolps5fhrTh18PjHJ0XYcKQl9MAIWB0uTJu9LOgY9fuw+5gnofTp/nq8tLEce6s7g47XEs3PzMG6roiP0fLm1qqQY+58cxem37s8puvUmWAdMSbETMjm9KzDFSibmigOl+eVrbvfAXeQ1HNNe5+3zaAae+OghJjTJVFS3wWrssaYmfVYHcjLyTQ6DCIiIooTo/+mIiIiopjNB3DtoG2zAayVUs4AsFZ5DADXAZih/LsLwEuAJ4EG4H4AFwOYBeB+NYlGNJyd8rflmPXwWlzxxIaYzxVrkiRRne0iqSQK53Mya0e+WL4dX/3Pejy3riym69d19qO9164Zi0N5j/bI8kNRn39wwq7PHt91zXqjWCftoz11cY0hGtFUZwKepN6Z960csl1d18y3mi2ZMSFmQuqTNtonb7zlSFu/AAAgAElEQVQ4lOu7JWAJ8oJyy6s78ML6cgCB1xBzut1wuCSK6+OTtY6U1eFCqyW8/qg9VifXDyMiIiIiIiIyCSnlJgDtgzbfAOAt5eO3ANzos32B9NgBYIwQYhKAbwJYLaVsl1J2AFiNoUk2omFLTVzEU6QJsnjG0NkXe8Wb2b2wviysyp5ovVtwLKbjL31sHS56eE3QMXq3q7x/SRE+21+vua/b6kBVBEsWnfK36Kqj9GjlGOzrtjrKrnOvbCzXbMfY0Rvez1JXvwPv76qO6tqJxISYCXkTYoZXiA1cvyvALxEpJZq6rWjv9SSbbA41ITaQfHK7pfeHKVC5qN6eW1eKm17cFnKc2+35fJgQIyIiIiIiIjK146WUDcrHjQCOVz6eDKDGZ1ytsi3QdqKU9uDSkpjPEc10vm/1TrgVVO8WxG8yPd7rLJnRE58fCTmmqrUXT685GtbaT7Fq67XjDwv3+nUIC7UuVjTz3z1WB97bWY09Ycwzv7V9IKm3eE+dt8sZANz4wlZc8eSGIcf02Z2o12jtF+4aX4P5zpOHEku1YW2HsUsE/GXRfvx18UEcrOv2226xmatjHBNiJqRWWTkMrhDzfUEKtI6YzemG0y1hdahJPM8T3GJzwqKUlTp9XizCWaBPD/WdVtR19ocspX1+fRkON/bg2rNPSGR4REREpJMeqwN/++ig0WEQERGRjqTnzX7cZnuFEHcJIQqFEIUtLanRIoqSR7yrSV7fUhn1sSbtBBhUr92FhTvNX6XioX+S6qdv7MTTa0rR3BN+UmYwq8MVdkJtyb76qCuUAKChK/QaU+c+sAr3RvEeb9PRFr/jKlq0q8N+Mq8AX3lsXUTnXrS7JvSgMLyzI/rn7lf/sz4uMUSr1eKp8By8ZNLiPbVGhBMQE2ImZDNJhZjTNfBC1x0gIab2UlWf6GqFGDDQNtHpHthmVIVYj9UJl1ui3+cHsrajD+c+sAqPrTgMKSU+LKzBU6uP4qYLJuMnl5xsSJxEREQUPwdqO3HuA6v8bs4hIiKilNGktEKE8n+zsr0OwEk+46Yo2wJtH0JK+aqUcqaUcubEiRPjHjhRvPTbXViwvSoh1T9m02qx+VX7+Lr/0+KIzvXqpop4hDSELq3yIjzn4OREpFotNpxx30q8MuhrFGytLAlglk+rxOfWlg55TxYoadnQZdXcHg61YOPPiw6guVv7PGpi0B3kPaJaefb2jtAtIw/UdKGzz44dFQNdfQ/WBl4ySCRlmjm1MCFmQqZZQyyMCrFepeRRTeLZnFoJMc8LzEnjctHQZQ0r0x9v6i/I7v6BirCa9n643BIvbyzH1+dsxJ8XHcBF08bikZvOhTDraphEREQUtltf3WF0CERERKSfTwHcoXx8B4AlPtt/KjwuAdCltFb8HMA3hBBjhRBjAXxD2UaUtB5bcQj/XFKMVTFU5MRTIqfTZj60Bpc/sSEu5zpY50lgLDvQgEsjrAxKNIfTM88aa2JlV1U7/rBwLypDrKHVqCSoPt3nvw7X3DVHAx4jpfSrSJuz+ihaBlWoPfCZdivP2+cVxJzEA4AfvLI96P5Zj6z1ftxjdWDa7GWYt9k/6ff0mtKQ11lZ3Ih/fFLkt019PmmJ189IIlPgEtIvTxALMyQEmRAzIZvT80M/uELM7nTH5QUhXOG0TLQMrhBzupCV4XlaeRNiSqXZRSePAwDsr0l8lZgaZ7fPnSNd/Z4yzu+cdyLaLDb849tn4r1fXYKczPSEx0dERERERERE2oQQ7wHYDuB0IUStEOIXAB4DcI0QohTA1cpjAFgOoAJAGYDXANwDAFLKdgAPAtil/Pu3so0oaXX0eea5op0vjHdlme9kdyxnDnfKvL3X7v04kqVnfON0Dpp/rdNYOyqRQn3uO6u0X7YiTTP86JXtWLKvHlc+uSGs50G062dFqtfuwq4An2MkjrX1YdrsZQH3t1psPh97nkfvhFERpqW4vjv0oCgs2F6F37yzO6Jjrn9usy6xDE5oBmP2gtUMowOgoQJViP3fh/vR2mPDe3ddkpA4HD4tEwNWiClrcFl9KsROGpuL8pZe74KBasvEKeNGAABaLHaNM+lLTYj5llJ3Kn803HvdGXj2lvNZFUZERJRieu3mWryXiIiIoiOlvDXArqs0xkoAvw1wnjcAvBHH0IiGpYLKNs3tvu389h7rGNLe73/e2xvW+aOZT99c1ur3ONxpvm3l2p9LIpTolEhRBUpMNPdY4Zvfckugq8+OcSOzAp7rSFNPwH3H2vyrzP6wcF9EcRrtubWhK8GC0WtG+Z9LImv9CQBFdfo+p1IBK8RMSK3M8k2ItfTYsPxgAxoD9D/Vg28pZHeAnrxqosmm3Ilid7oxbmQW8rIzvCW1aoXYuBGZABCwv6+eLFalQsynZWKnkuQbMyKTyTAiIiIiIiIiIjKcGVqKhVLRErzNHgA8u67M+7H6OX26vz7QcMOESr6Fs2ZXoO9ZqEoZ36+RKtwEXXNPZHPEvbaBOdHSJovfvjmrjuDCB1ej1WLz+2zDfS6WN4d+PkQjUcsJfbQ38HpoYTHgR9bc6waaObY4JMSEED8QQhQLIdxCiJmD9t0rhCgTQhwRQnzTZ/u1yrYyIcRsn+3ThRAFyvb3hRCB09IpzKYsAOibkPpkbx1cbhnTC8Hi3bX42uPrw/6B8S01DryGmJIQ86kQy8pIw3H52d4XZjUhNjI7Axlpwi8plSg9mi0THchKT0MuWyQSERGlHN83fEREREREetl9rB3byltDDzSJ7eVtmDZ7GQ43hl9JYuq5d0W41We6iGNC5O0w2/btC2NJmsZuq3ctr+fXD02+qeZvqwLg34IyEuEkDaPxbkF0LQyD0iHUSL79B2oH1hf7zIQJ4liYP5XvEY8KsSIANwHY5LtRCHEWgFsAnA3gWgAvCiHShRDpAF4AcB2AswDcqowFgP8AmCulPBVAB4BfxCG+pOOtEFP+l1Lig8IaAAOJp3BIKfHC+jJvpdbhxm5Ut/f5tUIMJw4A6AqQxOrVWEMsOyMdJ4zOGagQU1omZqanIT83M+EVYjany5tI7O73b5mYn8vqMCIiolT06IpDRodARERERMPA91/ajtteK4jb+fRKLqhWFjUAAHYY2CowEVJ9ti/Sz88ZZD64L8ZW839dfDCm4wOxOhJTIRaraOeWfx9DEjcJctSmFXNCTEp5SEp5RGPXDQAWSiltUspKeBYznaX8K5NSVkgp7QAWArhBeJ45XwewSDn+LQA3xhpfMhq8hti+mk6UNluQn5PhVzUWSnOPDU98fgTLDnp+0fUobQPVBFUo6gtlRpoIWCFmsXleML0JMYcb2RlpOD4vx2cNMeU86QJ5ORneOBLF4nO9bp+Pu/rtGKO0cSQiIqLUEuhmHiIiIiIi8oh35Vc82z3e8+7uuJ3LKOsON+t27kiTMNHWAwynOgIJ4EBt6Mq7wVL9SxTp64TZK0r1XENsMoAan8e1yrZA28cD6JRSOgdtH3ZsTmU9LiUhtb3Cc8fGdedMCtky0epwod8+sJ4XMLBml9o2MFiFWG1HH5bsq1PGeY4fPyorZMtENWNvc3oSYhPzstFqURJi3sRampIQS2yFmMXmmxDzrxAbk8uEGBERUaqRUqZc+wkiIiIiosHMNu88JHkSQ4DLDzZGfWw4l23ssuq+RtXhxh7dzq1XosoMyQwjY/ju81uNu/hwYILsYVgJMSHEGiFEkca/G/QOMEA8dwkhCoUQhS0tLUaEoKvBFWL9dheEACbkZfm1MdTyr8+K8asFhQAG2iuqa3Z5K8SCnOO/BdX43/f3we2W3muNH5nt12rQ18AaYi5I6VnjLDsjHVkZad7j1Yq0jDSBvOzMhFeI+V7Pd/2yzj4HK8SIiIhSUG1Hv9EhEBERERGlNJd7aNYiUJIm0uSN3nPmdqcblzy6Fn9ZtN8M8/NRiWc1nsoMyTBfWs8brecdxU6a7Zuvo7ASYlLKq6WU52j8WxLksDoAJ/k8nqJsC7S9DcAYIUTGoO1a8bwqpZwppZw5ceLEcD6FmPz+vb14avXRqI/fXNqC93ZWhz1eTYSpFVpq1VVWejpcbhn0B7+2ox8NXf1+x3srxJT/g1WIdfY7IKVn/TB13IS87CAtEz0JJrf0nNfmdCErIw2Z6WmQ0vMiZXjLRJ8KMd/qtK5+B0bnZiU0FiIiItJfc4/V6BCIiIiIiEwt1unveZsrhp4zSebU1Zv4V5c0hRyrR+JJD3pUjJmxXeKDS0uMDoFCMPvLgJ4tEz8FcIsQIlsIMR3ADAA7AewCMEMIMV0IkQXgFgCfSk8acj2Am5Xj7wAQLOGWMFtKW1Bc1xX18S+sL8ODS0vCzmDbBlWI2Rwub9WV73bNYx1u74u6Oq7bmxBTWyYGPl5NfNmcbu+4CUrLRK1Mca9PssnqdHmTdxnpwnst/5aJmQlvmah+3hlpYtAaYqwQIyIiSiUOlxsWmxPff2m70aEQEREREZlSpGtPBdLQpd9NaHpPqKtfgl5l2ZlUYMLclS4+2lMb0/HS9Oma8Jgx+WzGBKqWmBNiQojvCSFqAXwZwDIhxOcAIKUsBvABgBIAKwH8VkrpUtYI+x2AzwEcAvCBMhYA/grgT0KIMnjWFHs91viiUVTXhWfWlMLlluizO9HR5wjZqjAQKSWK67vRZ3fhaFN4fWOHJMScbuRkpg0kxILE0u9wDakwUxNCFrVlYpDEnNoa0e6TEJs4Khsut9T8JWGxDWyzOpSEWGYaMtPSvNfytkxUKsS641wh1maxoShIwtJi83xOJ4zO8X5+6oTZaK4hRkRElDJue20Hzrn/c6PDICIiIiKKSDwnknusDpQ1W+J3QjKlWJ4zSZK30Iwz3vPKyeDNrZUJLzCJhdnbL2aEHhKclPJjAB8H2PcwgIc1ti8HsFxjewWAWbHGFKv9tZ2Yu+Yobp45Bf1KEsjmiC4hVtPe701I7a3uxJmT8kMeoya8/FsmpiNLqboKViFm9UmIDa0Q8/wfbA2xbm+F2MB5JozKBuCpqBqV7f+U8a0Q67O54HJLZGekI1OtEHP6VogJ5OdmwmJzwuWWSE+Lz8vvC+vL8fHeWuz95zc096uJwMljctFqsXk/FwCsECMiIkohu6o6jA6BiIiIiChivvPHRXXdkFJGXcl122sFOBhmp6t4T1tvK2/T9fyRiFeSMZyKomRJMEUjWVpGxkO0eRy9K6P+9VkJiuq69b1IEOZOb0VOz5aJSWva+JEAgGOtvajr9KzHZXNGV0JbXO/5BSQEsLc6vEkaNfmmJqSsDpdnDTGNCrFuqwP/+qwYVocnPt8KMbtPhZhvhVewNcR8WyaqlWQT8jzrbHX1Dc1E99oHEmJq4s3TMtETq8Pt9qkQS0N+jieh5ruuV6zqO/s9VXwBEoU9yrVOHJPrvYugU/lcWCFGRERERERERERmUh+iHWFVay/mrDqiWYkRbjJMS2efHVWtvVEfH0i88wXtvfaQ12vqtoV1LnVONdmE24lMlZYs/exgXALGzO0U1Tl71XPrSuN6fjUHEs61AQTt1hbsq2iGZyETYhpOHj8CAFDV1od6b0IsugqxovoupKcJXHrKBOyt6QzrGDWRZfOtEPNtmegTS0FFO97cWoUDtZ4nodXh9ia8vBVi/Q5vlRQAb4JKizch5nDDoVEhNpjF5vTGpe7PykjzVog5XdKvQixPSYjFs8xTrfrq7NP+ZWixOpGZLjBhVJa3Aq6r3zN2zIisuMVBREREREREREQUq1CTxne+uRPPrSvzTmJHW022rbzV7/E3n96EK57cENW5gol3muHCB1fH7Vx/WLgv6H4jK3OC2VzaGnqQj3CeIWZOCCVCmyV4otVMNhxpiev59lYHzlvc90kRnltX5rft+ue2xPX6icSEmIZJo3ORlZ6GY2293oRYoOqjVosNlUHunCiq68aM40bh4unjUNZs0UwqDWZ3qpVcbkgpYXO6lJaJ6UNiUdfH6lMqtawOF+zKcWpirMfq9FZvec6r/eImpfRWUNldnjXEhADGKkkjrdh7bU6MH+nZ393vOTY7Ix0ZyhpiDtdApZlnDbFMb0zxoibE2gMkxHqsTozKzsDo3EzYnG7YnC5vhdgYVogRERGlBLP3KSciIiIiihd1bk/9EziadFhdRz9uf32n37Zwq6pUzd3BK9mirQaJtYok1DsD3znO/hAVYv9ZeTjGaBLjgc9K4n5Oo6t5El3UxreUgb23s9roEOKGCTEN6WkCU8ePQFWbb8tE7YTYnFVHcffbu72P3W7pnZCRUqK4vgvnTB6NC6aOBQAcqA1dJaZeS0rA6ZawOdzIyRyounL4tExUK7/U8l71f7vLDbvL87HTLdHcM/ALLdAaYr12zxpgAGBzuGB3SWSmp3nX2dKqwOq1uTBOTYj5tEzMzFATYnIgIZaW5lMhFs+EmCeujl7tZKPF5sSonAy/ZBzXECMiIkotL6wvCz2IiIiIiMiEjKjM8V0GRUtNe5/3JnQtfXYnZj2yNt5hJcQza+Lbbi6VkgW+z8VUzA/pkfSqaQ/cbjB+zPPdCHQzqrqmt9kTi0yIBTBt/AgcC6NlYle/3ZsIcrjcmPXIGny6vx4A0NxjQ6vFjnNOzMcXTxqtrCMWOiHmWwFmd7r/P3t3Hu9YXd+P//U+a+46+8YMOCiIZWmpTF3qUqu4ob+iVvu19Wdpa0sX/T5o7ffbYm2ttVqXuvf3rRZFBQuiVflCRQXZFBAHBhhghoFhGIZhZu7M3NnunuQsn98fZ8lJcpKb3JvkJJnX8/G4kntycs4nuZl7Y155v9/IRxViYciUXEs0H2u26JVVYxVdH45bevYdSPQBjfapvi+lQKngBhVilq5h9UgOmlT3L1ZKYaboYkVFS0Xb1GBqYctE348DuKBlYhRKtaZlYt7x4nlkx+tWiJkYHQjCuMk5hzPEiIiI+synb9mZ9RKIiIiIiBpS+Yby1+/Zk81C6njFp+6oG3jNFntz9hbQ+mjh5u2HWnzE9rq2wQDv+GwR775yc5tX0/vmqzLsN7ftOFz3+i7PwxiI1fKcFUMVFWLpT+yC48cVW7NFD0emi9g9HrRQ3H4gmOt1zvolGM2ZeN6q4YYqxJKBmOP5KDg+bCN9hlhUITZb9MqGQBZdP55BBpQHYk6NCrHJRCBWDAMxUxdYhoY1oznsP16eds8WPSgFrBwqb6loGzoMPVirm6wQ06XlFWLjicq3WgM1pwsORnIGRhMVYifmHIggDuiIiIiodz12oDv7+hMRERERNaLZeVCRbn/jOav11Rp9E9l7bLZDK+lOP3hkrKH98o6PozXeb+0EaVPTRq9GscjJPkOt0RaVky0qdMkKA7EaNq4YRN7x45LHWr9IC64fXxcFTVEq/NThIBh7/poRAMBZa0ew89D0vOcuVFSIFdwgELOjQCzZMrFQapmYTKMdT5WteX+yQqzGDLG0CjEzDLbWLx3A/hPlfyxmwnOvGI5miAW3twwNRtjesej58fmSLRNb9Q8nWbp9vMYv6Km8ixHbwGhYDTaZdzAxW8RozoSuZd0Nl4iIiBbroi/elfUSiIiIiIhaptVvy//3wwfw5//5wPw7NuGeXY2HeM2++7bveHtb0D387PwFCyejbml11+750MnCkaS8Uz9IpcD7v/Nw1ktYFAZiNTxnxVB8edmgiYLrp/5jDCqpgu2lSrEgKIrCqhE7CIHOWjOCvcdm4+trKWuZ6PkouB5ypg5L14Pz1KgQKzjlQZpTo0LM9Wu1f0wGYh6KrooDsQ3LBqr+GEX3b/lQRctEQ4OVqBDzwvMZupRVabVCND8MAI7PzjdDLGqZGFSIcX4YEREREREREVHvOjyVjzs09bJGKjOUUrh/z7EFhQX/81sP4UfbDlYcr+nDlKn1PlwrfHvLs207NnW/b9//bFkntFZ7xafuaNux26VbwspGHK0ze9DvgjvCQKyGjYlA7PSVweViSqvBguvFwVM0syvqoTtbdDFg6tDCKqSoUuzJearEku0ZkxViplGquopMJ2aIJSvEip5XUSFWmv/l1KgQm6yoEHP9oGUiAKxfNoCDE/myktLofsYVYmHIZRsajGiGmFcKDA1NwmBPa3mFmKVrNWeITeddDNvJlonBDLGlnB9GRETU89r5f5SIiIiIqLv9xqfuxJu+eHfWy1i0Riqobnp0DO/48r34ry37ShsX8OZyo23RqM/00M/9R9sO4nM/2cnnasJtj9ef29UKUc6wWNvrjDTogjyMgVgtpyzNxaHO6SuHAaS3TQyCIwXfV3FQNRcHYh4GLT3e96y1QSD2xKGpuucuuj6GwtsVPR95x4MdBkmV60i2TEy+IVRYZIVYsapl4iBcX+HQZClYi869crj2DDHHV/H5om0jOaN1FWLhDLHTVw7VnCE2FVaIlbVMnHPi74mIiKh3veeq+7NeAhERERFlZK5PPhzVyBv/zxwNRpk8fXRmQbdvxW2ycvvjh7JeQs+7YeuBrJfQlHbNLntqfP5xRiere3YdzXoJHcFArAZD13Dq8kEAwHNXBRVihRqBGAA4fmmWWFQ5NVf0MGiXArHTlg/CNjTsPDhPIOb5GA7b+yUrxCyjdiA2W3TjIC7ap+j68R+3ZNgVVbJVmpynZSJQ3sN3pqJl4lQUiJlaXFnmhIEhgDhgbGkgNl3ASM7A2iU5nEipEAvuh4/RnIkhS4cmQcvEiTkHSwetlqyBiIioU0REF5GHROQH4feni8hmEdklIt8WkZPuj9vJ8qKdiIiIiDrr8FQez6SET61QWSUhCyzf6YJii7paNQvqj76xpSXHOZklu37V0g3VO+3Wzlaf1BsYiNXxnBWDGLGNuAIqLRCLwinHU3FFVvTplJmii0HTiPfVNcGZa4bnrRArOD5GwvZ+MwUPSqEsECt46TPE8on1OV5QsTZsGXEQZRtR1VZ6hdhk3o0r2gpOWCEW3mZ9GIjtPzFbOncYiA3bBixDi0M3S9fiIM31fbheZSBmYqplLROLWDVsY/mQhWMpgVj0+AzbBkQkPveJ2SJbJhIRUS+6DMCOxPefBPA5pdQZAI4DeE8mqyIiIiIi6jMv+tht+I1/vbMj52q2Wiva/5F97ZmfdrzF1Tm9VI12Mrvy7qdxaLL2/KdOunHrAXz0ph3z70jUJAZidbzz107FH7/iubCNsH1haoVYEH45iRaFyZaJA4mWiUAwR2znfIGY52PYDoK0KDjKJVomOol1TIWh1FzRS60Qswwtbg24fCgI9twaM8Qm5hwsH7KgSanlohXNEFsaBmJlFWLB+YZtA3YiECurEPNUXCGmt6FCbHy6gJXDNpYOmjg+Ux2yJUM7ABgdMPDfj4zh+KyD08IKQCIiol4gIhsAvAnAV8PvBcCrAXw33OUqAG/JZnXZ2DFWuzc5EREREVGvalVlVf1z1L7uT65mRdbJ6JbHDma9hFjRSy/oIFosBmJ1vOHcdbjswjNLlVludV/ighNViPnxP9TZYqlqa8guD8ResHYEhyYLqe39gOAPXtH1MZKLArHgWGUtE1MqxOYcr2x9Rc8LAi1Di48VBWJOjV8oE3MOlgyYsA0dRa98hljO1LFy2E5tmThk68iZehx82YYOQ0tWiPkwNIFIMhBrVYVYAStHLCwftDBdcKtCy+jxi1pQjuZMHJsp4t0veQ4u+fWNLVkDERFRh3wewN8AiP7YrQBwQikVfcpkH4D1WSwsC0+NT+ONX7gr62UQERFRRkTkLBHZmviaFJG/FJEPi8j+xPaLErf5QNhq+gkReX2W6yeaz+d+shPff3BfS4956dVb8PV79sy735ZnjqduT74vSETUrG6oFjXm34WiVoNR+JUUtS8MAqQgEEpWiC2rmFP1/DUjAICdh6bxotOXVx0vCrsqK8Rso1QhFoU+rufH7Rlna1SImbqG0bD9YrQWt0bP2MkwELMMDQXHQ9FTGLRKmen6ZQPYf6L0hy+qvhqyDOTM0n62ocGIZ4gpeL6KvweClomTcy2aITZVwMozVmJZGPadmC1i9Wiuao0j4eP5Vxc+H0XPx0XnrWvJ+YmIiDpBRN4M4LBS6gERedUCbn8pgEsB4LTTTmvx6rLxt999JOslEBERUYaUUk8AOB8I5qwC2A/gegB/iKCl9KeT+4vI2QDeCeAcAKcAuFVEnq+Uqv70M1EX+MJtTwIA3vbCDS075i2PHVrU7b9051MtWgkRUTZYIdaAuGViRWVVVM0FhDPEwsuzcUjlVlWIlQKx9LaJ0fFKgVhYIWZqMHQNmpT2iVoWAkEIl3dK3wctD1VZhdiyuGVi7Qqx0ZwJ29BQcIPKLjMRZG1YNlBVITZo6dA0Qc4o3U/b0ErtHf1gHVHFGBBUabWiQqzgepjMu1gZzhADUDVHLKqgi2ayXXj2GoZhRETUi14G4LdEZA+A6xC0SvwCgKUiEn3AaQOCN4KqKKWuUEptUkptWrVqVSfW23a1PrVKREREJ6XXAHhKKfVMnX0uBnCdUqqglHoawC4AL+rI6ogqJD+qfs+uIxibyDd+25TPuQuaL7voRKVGcq17jsy0/4S0OO3v1EmUOQZiDbBqVIgVEu35iokZYrOJCrHBihliUXAzWSMQigOxMMSKKpyiUM4ytPg8U4XSMeYcD3OJ9TmeQqGqQsyMr0sTt0w0tfj+RC0TAWDD0qBCzA8rzGaKLobC4C5nhuvTNYgIjPB2rqfg+X5FhZiBmaIHr0al2nyKro9//sFjeGjvCQCIZ4gBwLGKoZ/RY1QZTBIREfUSpdQHlFIblFIbEXyy+Xal1LsA3AHg7eFulwC4IaMlEhEREWXpnQC+lfj+fSLyiIh8TUSWhdvWA3g2sc9J1W6a2mPj5Tct+hjv+urmhvZLdm3Kou1YNDplIQRStn7qTrMOC2ap/zEQa4Adz+4q/6WQDMSSM8SKrg/PV5grehi0yrtSVrY9rBQdM2rxN5moEAMAUzmDncAAACAASURBVNfifaIKsWWDJmYrKsSKbrCeZIXYaM6ErglcP/3ck3kHowMGbEOPK8ySgdj6ZQMouj6OzBQAANMFL65kix6j6L9xy0TPh+MrGFp5IAaUqreatfPQFK68+2n8+X8+AABYOWzFQeOJ2fKg8eh0EJBF1xMREfWZvwXwfhHZhWCm2JUZr6ftfF/hhq2phXBERER0EhIRC8BvAfivcNOXADwPQTvFMQCfWcAxLxWRLSKyZXx8vGVrpZObUgqf/PHjeGp8ekG3v3bz3prXiQQdoWaLjb/XllZpVk/UwpH610KLF4h6CQOxBtSqEEuGWkXPL/t+tuhipuhWVYhpmsDQpGYgVlkhVpohVgqcouBtOqx+WjViY67oVgRiHhzXh6ULRgeC6qmRnAFDE7gpFWIF10Pe8YMZYrqGguvFM8gi65cOAAD2h20TZwqllpBRhVgU3MUtEz0F1/OrWiYCtavk5hPd7ngYfq0csbE8nI9WWSE2PlWAZWhYEj4GREREvU4pdadS6s3h5d1KqRcppc5QSr1DKVXIen3t9sH/+yguu25r1ssgIiKi7vFGAA8qpQ4BgFLqkFLKU0r5AL6CUlvE/QBOTdzupGo3Tdk7OJnHl+58Cr9/5X3z7ttsWAUA7732QZz9oZsXsLLGXPGz3W07NhFRpzAQa0AURhXcypaJpQDKCSuqIsdnHCgFDFjVrfosQ6sdiHnRDLEgwIlniBmlloTRbaPrVo/kwpaJXlyJVfSqK8RGciZMXUttmTg5FxwraplYCFsmWkapsmvtkhwA4NBk0Nf4yHQBy4dsAEDOjAK7YJ3ROlzPh+sr6CkVYlMLrBCL1vrmX14HUxecumwQS8NA7PhMEXNFDyp85XB4qoBVwzYki1pyIiIiarlv3ffs/DsRERHRyeR3kWiXKCLJweFvBbAtvHwjgHeKiC0ipwM4E8D8yQTRAp319z/CFT97Kv7+rp1HAKBtrQNv3n6oLcddjD1HOTeMiLoLA7EG2GH1U2WIVd4yUcWzvQDEbQWHKlomAmEg5tVomejUrxBLhmnRfLFVIzZ8BUzOOXE1WDQDzErMEBvJGTD09JaJE3PBeUYHTNhGKRBLVoitWxJUiEWDPg+cmMMpYUgWPUbROqMAzPEVXE/BTMwQi+aOzTRRxp0UVYj97RtegIc+9DqsGrFhGRqGbQNbnjmOl3z8tvhTK4en8lg9ai/oPERERERERETUvURkCMBrAXw/sflTIvKoiDwC4DcB/BUAKKW2A/gOgMcA/BjAe5VSHJhDbVNwffzLDx+Pv99xcLJlxxb0xge/b91xOOslEBGVqU5rqErU/i9ZEQaUB2SO55cHYlNBIJZaIabXqxALzhHNEItCr6glYVDhFQZi+VIgBgBHZ4oYyRk4NlNE0VNxy8MoJBvOGTC09AqxZCBmGTom5pyqGWLLBk1YhoaDE3kUXA9HpotxSJYM7ABARGDqAtcL5qklK8SisG96gcM4o8qy0ZwZzzADgGVDJn66M+jtvWMseJFxeLKA564aWtB5iIiIiIiIiKh7KaVmEMxRTW57d539PwbgY+1eF9F81EJ6IrbYdfd3rvPCx364A2+/YEPHzkdEVAsrxBoQzcWqbplYMUMsEYgdDWdZ1aoQqzxW5TEHLB0iyZaJtSvEVoeB2PHZIgZMPQ7copaJ0fysJQNmHFJVmowCsVxYIeZ4cDwfRqKyS0SwbkkOYxN5HAyrxNYtDSrEchUVYkApvKusNItCrOkFt0wM1hoFa5EVQzZypob1Swfi8vPDUwWsHskt6DxERERERERERESdFo0r6SfffWBf1ksgImKFWCNqzhBzEjPEPB+OW/p0x9HpoEJssMkZYtE5LEODpWtx+BOFcsl2i1FYtnI4DMRmnLh9YNH1UXSDlomvfP5K/PPF5+D8DUth6FJWyRY5PBX8oV09YsMOzxG1XExaO5rDwYk8DpwI9l+/NKgQyxlRIFa6v4YmcDwFz1dlwVoUiM0ssEJsMu9gxDbKqs4A4B/efDYA4JrNz+Dep44i73iYmHPiwJCIiIiIiIiIiKjbvf3L92a9BCKivrSoCjEReYeIbBcRX0Q2Jba/VkQeCHs2PyAir05cd6eIPCEiW8Ov1eF2W0S+LSK7RGSziGxczNpaqdQysTxISlaEVbVMnA4qxFIDMb12hVgUlNmGBsvQMFP0wu/1qttOF1wMWXo8k+vYTFAhZuqCohdUeFmGBtvQ8e6XboSmCUxNg+NXl2UfOJGHCLB2SQ62oWOu6MFXKKvsAhBUiE3OYWxiLv4eAHJhYBcFd0BwW9f34fgKulbaPmQvrmXi5Jwbt4FMuuA5y3DBc5Zhw7JBHJrMx7POOEOMiIioP2y8/Kasl0BEREREVNMzR2ew8fKb8INHDrT1PNH7cpHemChGRCe7bph/uNgKsW0A3gbgPyq2HwHw/yilDojIuQBuBrA+cf27lFJbKm7zHgDHlVJniMg7AXwSwP9Y5PpaQkTCNoflM8QKTiIQc1VFIBZViFU/xHaiyqtSWSCWCKNyiQqxKEiazrsYzhlx6DbneMiZWlmFWGWgZdRomTg2MYdVwzZMPbh91M6w8vZrlwzg0MRB7D8eBWLRDLHqlonBuRQ834epVVeILTgQyzsYydV+6m5YOgBfAY/sOwEAbJlIRETUB/IOZ94TERERUff6/K07ccbqYQDADx4eq7r+6/fsadm5HK/8w+4/2XGoZccmIupni6oQU0rtUEo9kbL9IaVU9FGI7QAGRGS+Mp2LAVwVXv4ugNeISPaRYcjWq9scVs4QS34fBWIDNVsmpr+pE7dM1HVYiXApCsesxDqmiy6GbaPsHANWcDvHU3A8VXYMIKza8tIrxNYtjcItDdPFKBAr/xGsW5JD0fOx7cAElg2a8bmTgV3yXEHrRVXW3lDXBAOmvqgZYmkVYpH1y4L78dDeIBBbxZaJREREPW/X4emsl0BEREREVNPnb30St+043JZj7z06W/f67z+4vy3nJSJqqS5IexYViDXotwE8qJQqJLZ9PWyX+A+J0Gs9gGcBQCnlApgAsKID62uIbVa3OUxWjEUtE6MA6WjYMnHIbm6GWFwhFlZ6AUFAFT1MydsGFWJmWVvGnKHHoVnR9asCMUOv0TJxYg6nhO0PbVODUqW1Jq0N93lw74m4OgwAcmb1DLEofHO96kq1IdvATHGhFWIuRnO1A7ENcSB2HABbJhIRERERERERUeDDN27Hh2/c3pZjX/9QY8FU9Ttz9V36zVKjrS//9Kkmb01ERJF5AzERuVVEtqV8XdzAbc9B0PrwTxOb36WUOg/AK8Kvdze7aBG5VES2iMiW8fHxZm++ILahl7VIBFAWakWB2JKwcilumWhWt/az9HotE714nyhESrYhtBLtFqcLLkZsAwNmKYSyTR2WoaPgeiimBFGmVt0yUSmFsRP5UvtDvbzKKymaGTY+VcApS5OBWPVaDU3g+j48v7xCDABGcgamFlUhVrtl4rolAxABth+YhCbAiiEGYkRERL3u2vv2Zr0EIiIiIuoD3/j5Hnzj53uyXkZTnBrvIxIRUXPmDcSUUhcqpc5N+bqh3u1EZAOA6wH8vlIq/uiCUmp/+N8pANcCeFF41X4Ap4a3NQAsAXC0xpquUEptUkptWrVq1fz3sgWslLlfhbJALGhROGgZMDTB8VkHQL2Wiel/yOKWiYkZYnYi8CprmZhPaZlo6rB0wUwhCNbsqgoxqWqZODHnYM7xcMrSqEKsdDyjIsiKKsQAxPsH50mbIVZq3VjZenHI1jGziBli9SrELEPD6hEbrq+wctiuCuOIiIiot+w/MYdrNzMQIyIiIqL2uO/pY9h3vH5bwmZ0zxAYIiJKakvLRBFZCuAmAJcrpe5JbDdEZGV42QTwZgDbwqtvBHBJePntAG5XSjVbQdw2tqGhUDHMPdkysej6YUWWxAGVqUtVy0EAsAx9/paJRqllYlR9BQCmocWfCpkuuBiyDQxapWqpXNhqcabGDDBT1+D45ec+cCIPAKUKsYqKtKSVQ3YckpW3TEwL7wSOl14hNmwbcWjXDN9XmC64dWeIAcCGZYMA2C6RiIio1+UdDy/7xO1ZL4OIiIiI+tjv/Me9ePkn78h6GURE1GaLCsRE5K0isg/ASwHcJCI3h1e9D8AZAD4UzgrbKiKrAdgAbhaRRwBsRVAV9pXwNlcCWCEiuwC8H8Dli1lbq9kpFWJReCUStkx0gxaF0UyvZFBVdaxagZjnQ5OguiquEDPKK8SiKrKpvIORXHnLxAFTh2VomA6rr6yKloeGVl0hNjYxBwBYF1WIGbVbJmqaYM1osF9ZhVi4huT5jHCGmOP7MCqOM2wbmFpAhdh00YVSwGiudstEAFgftnNcPZKrux8RERF1ty/dyRkJRERERNQee47MYPPu1AZVLdOKz/sLS86IiFqifqowD6XU9QjaIlZu/yiAj9a42QU1jpUH8I7FrKedLEOrmiFWcIPwyjb0eIaYZWhhEFaIg7G0Y9WaIVZw/TgAi6qzkgFVFKYpFVRKDdsGdE3iNow5U4ela3E7QrOqZaJW1Xf4wERQIXZKWPFl1QnEgCAI239irrxCLK1lolaqEKtsvRhUiDUfiE3OBa0o67VMBIANy6JAjBViREREvcrzFfYdn8t6GURERETUp1716Tvbfo45x6v5oXkiIuos/jZukG3omC2WBzgFNwjALCM5K0uLK7bS5ocB5VVelYrhMYFSu8PKFoZFz8ds0YOvgOGwUmrQCtow5qywQiyfXiFm6gLXr6gQOzEHQxOsCsOjZEVaZctFAFi7ZADAcaxbkqwQ08r+G9xWw5zjwfUUDK18HUO2EVexNWNyLrjN6MA8FWIMxIiIiHraidkizv/IT7JeBhERERFR05IFXWkFYt0zJIaI6OTSlhli/SitZWLB8WAbOkw9uK7oBjPEosqwoQW0TCwkArHSDLFkQKVBKeD4bBEAMBIGYlEIlzM0mLqGmaJXdoyIoWlwK+7H2EQea0Zz8ZyvsgAupUJs/dIBGJpgbSIQK1WIlYdpjufD9f2qYG04t8BALN9YhVjUMnHVKFsmEhER9aLf+8rmrJdARERERLRoadmXSt1KRETtxgqxBqW1TCx6PmxDC1oDuj6Kno9Ry4SpB3/UalaIheGaUqqqB3DB9eJAykppQxgFXIcmCwCA5YNW2bkGwgqxeP/KGWK6wKmYIXbgxFxZtVdZy0SjOhD7o5dvxCvOXFnWTjFnVrd3DNozKrieisO2yLBloOj6ZRVxjYhbJg7UD8TOXjeKZYMmfnn9koaPTURERN3jsbHJrJdARERERBT71n17cd76JTi3yfea0maInfX3P27qGJwgRkTUGgzEGmQb1W0OC04Q5ujhrCzH82HpAj1sDzhUp2WiUoDrq6rKqfSWiXrZbQHg0GQw92vZUBCIRVVpOUNPDdAiplY9Q2xsIo9fOXVp4r6Wzlc5+wsAVo/ksHqkvPJq/bIBvP6cNdi0cXnpXLrA9fzwfpavI2r1OFNwYRlW1TlqmQxbQc5XIbZ6NIeHPvS6ho9LRERERERERERUywe+/ygAYM8n3jTvvpKIsFgLRkTUPdgysUFWSpvDghtUiJl6NEPMh6lr8aDMWgMzo5AqrW1i0fXj0CsKtpJzuaLbHpwIArHlYSCWnFuWrAqrDKKMihlivq9wcCKPU1LmgaXdvhbb0PEf796EM1YPl86laXB9BdfzqyrEhuzgsWm2bWKpQoxZLhERERERERERdZ+7nhzPeglERJSCgViDbENHwfXKtgWBWGmGmOMFlVBR+8LBOi0TgfRArOD6sMNwqzIYS942rhCLWyYGAVHO1MpbJlZWiOnlFWJHZ4ooej5OCWduJc+bdvtmmHoQIjq+glFRCTey0EAsnCE2bDMQIyIiIiIiIiKi7hN1OAKAlI6JRESUEQZiDUptmeh6sE0Nlh60TCy6YYWY2WAg5qVXiNl61DIx+G/OrN0ycelg0DowOmcU0EUqK7yCNoalv8RjE3MAUDZDbCEVYmlMXeD6PjxfVbVeXHiFmIth24CxiHURERFRd3v22GzWSyAiIiIiSvWn39wSv5/WCV+9azeePDzdsfMREbVLN8xDZKrQoFotEy1di6uuHM+HZUgchA3Uapmo12mZ6JVmiEX/Ta8QK2AkZ8SB1YCVaJmY2N82KlsmanD90nkPnAiCtWSFWHKGWOWMs2YYusDxVBiIpc8QW0iF2GiO1WFERET97KIv3JX1EoiIiIioT2x99gTclA+lL9TN2w/hX29+ovEbLLJC7KM37VjcAYiIKMZArEG2ocP1g3AnUgzbG5q6BsctzRCLgrCheSrEKivOgm1eHGKVArH0CrFofhhQCsRyZnkgVlUhpgUhlQrrtVMrxJIB3KIqxDTknaDNZGWFWNTycKbJQGwq72AkZy54TURERNTd8o6HqSZfHxARERERpXl03wTe8n/uwedvfbKh/X+8bazla9h9ZBobL7+p5cclIqLmMRBrUNRGMFnVFcwQ02AawQyxuGViolor9Vh1ZogV3VKFmFlnhtjByXw8PwwotUwcMPW6M8CiVoNRsDc2kYdtaGXhWr1ArRmmrmEuCsQqjhO3TMw33zJxdIAVYkRERP3qIz94LOslEBEREVEfmC26OBB+EHzH2GTV9RNzTtW2azbvbfk63vrvP2/5MYmIepF0Qc9EJgsNikKmguvFQVfB9WAZGpRSYctEFVaIBddHoU/VseaZIVbZKjE5QywKqGaLXo0KMS01QIsYYQtE11cwdODAiTmsW5KDJJ6Nydsbi2mZqEk8OLSy9eLwQmeI5R2sHc3NvyMRERH1pH3HOzePgYiIiIj6w77js9iwbLBs29kfurlq7MbBiXx8+foH9y34fNIVk3CIiKhZrBBrUFQhlmxzWHDCCjE9mC8Wzf+KKsQGa7VM1IPtaRVis0Uvvl0cjJnpAdfSwVLrwJedsRIXn38KBsIWjpHKIMoMZ3k5YRg3NpHHuiUDZfuUzxBb+FMkWRWmV7RMjNpJLmiG2ABbJhIREfWrfcdns14CEREREfWYt3/p3tTtkxWdif78mgc6sRwiIupSrBBrUFQhlgyxip4fzBbzVNwa0NIlEYjNUyFWMxALbpfWMjF5eXmiZeJLnrsCL3nuirLjA4Ctl4dycYWYF7ZMPDGHlzxvRdk+yRBtMYGYlThOZctEQ9cwYOpNzxCbnHOrPt1DRERE/WP3+EzWSyAiIqIeIiJ7AEwB8AC4SqlNIrIcwLcBbASwB8DvKKWOS9Ae5wsALgIwC+APlFIPZrFuaq3DU/n5dwIwW/DqXv/gM8cbOk43tP0iIqLmsUKsQbZZapMYKTheXCE2Wwy2m7qGlcM2AGDFsFV9ICRbJpb/EVZKYaboxtVTVhyI6VW3BYBlQ/WPDwCmUf4XOgqmHN+H5yscmirglIoKMRGBbWjQNamq7GpGMgQzUo4zZBtNVYgVXR8Tcw6WDqbfbyIiIuptrA4jIiKiBfpNpdT5SqlN4feXA7hNKXUmgNvC7wHgjQDODL8uBfCljq+UutpMsX5gRkREvY2BWIOiyqy8k2iZ6AYtEy1D4konU9fwyxuW4r/f93L86qlLU4+VVm0WHVspYDCcr1U5Syx5WwBlM8TSjl95GQBMrVQhdngqD89XWLe0eiZXEPQt7uMuyRAsLRAbyRmYnueTOUnj0wUAwNolnCFGRETUj/715ieyXgIRERH1h4sBXBVevgrAWxLbr1aBXwBYKiLrslggNW/j5Tfhr7/zcMuOJ4so82KBGBFRb2Ig1qBSVVcQYimlwpaJQYVYNFvMDPc7b8OSmn9Yo2MVKgKx2WIQqkUVYlG7wpyZmOmVrBAbTJ+lFR1fpHp2V1S15XoKB04E5eSVFWJAUBG3mHaJQHm7RSMlXBuydUznnYaPd2gyWO/aUQZiRERE/cb1fNyw9UDWyyAiIqLeowDcIiIPiMil4bY1Sqmx8PJBAGvCy+sBPJu47b5wWxkRuVREtojIlvHx8Xatmxbgew/uS92uov8qldqN6LbHD8PzVdV2IiI6uTAQa1BUpVUIK8QcT0Gp6uDIaqCqyq4ZiAXVUgPhDDF7ngqxZTVaB0b7WLpWFcpFVV9Fz8fYxBwApFaIWbrW2kBMqz7WsG1gpokKscNhILZ61F7UuoiIiKj73PLYoayXQERERL3p5UqpFyJoh/heEXll8kqllEIpL2mIUuoKpdQmpdSmVatWtXCptBCPHZjE4wcnG9r3C7c9iXP/8WbsOVI9l3Y639wc+8jYxBwcr/w9vP96YB/GpwoLOh4REWXHyHoBvSKa4xXNEIv+WxkcNRIiRQFXZcvEmYoKsdNXDmH1iI3nrByK90nOB6vZMtEoBWKVomDK9X2MhRVi61IrxDS4vl+1vRnJqrC0lonDtoH9JxobegoAByeCfdewQoyIiKjv+Iqf2CUiIqLmKaX2h/89LCLXA3gRgEMisk4pNRa2RDwc7r4fwKmJm28It1EXu+iLdzW87+dvfRIA8PTR6kCsUqMdE1/68dvxzl87tWr7az5zZ8PrIiKi7sAKsQZVhlhRdZdtamVVYY0EYlatQCyslopmiG1cOYT7Pngh1i8tBVbJarFl8wViRkogppdmiB2YmMOQpWM0V52L2kYrWiYmArGUYwUVYo1/OufQVAGmLlheozKOiIiIetf7rn0o6yUQERFRjxGRIREZiS4DeB2AbQBuBHBJuNslAG4IL98I4Pcl8BIAE4nWinQSUM0VC8Zuf/xw1bbJBVacERFRdlgh1qDKNodRmGUbWlnw1FQg5tWfIZYmefylA/VniKUFYlFI5XhBhdgpSwdSZ51ZhpZaYdaMZJvEtAqxoWYDsck8Vo/koKUci4iIiHrXP/339qyXQERERL1pDYDrw/c1DADXKqV+LCL3A/iOiLwHwDMAfifc/4cALgKwC8AsgD/s/JKpHdrdbOAw2yMSEfUFBmINilomVlaIWUZ5y0TLmD+siYKmmhViVu0fi64JdE0wZOmpVVfJ46eFc9E211cYm5jDuqXV7RKBIOjLt3KGWMpstSHbSB10WsuhyTznhxEREfWhr9+zJ+slEBERUQ9SSu0G8Csp248CeE3KdgXgvR1YGmWN3biJiLqOIPtCF7ZMbJBVUSEWzRCrbC1o6bWruyKGrkGT6kBszgnCocE6FWLBObSa88OAUhCV2jIxrNpyPB8HJ/NYWyNgsg0tNcRqRlnLRK16LTlDQ9HzoRr8GM+hyQLWcn4YERERERERERHV4flMxIiIqBorxBpUapkYBGHJlolmWcvExkIkKwyDkkozxOYJxAyt5vyw5FrTK8RKM8ROzDpYVmMe1yUv3YiZ4uJ6IRvzVIjZpg6lgtaRUQVePYcm83j5GSsXtSYiIiIiIiIiIupvV//imQXf9v49x/COL9/bwtUQEVG3YCDWoKjaas4JQqtky0QrEfaYKVVZqcfTtaoKsdIMsfo/FsvQsLxGkJVca2qFWBhSzRRcFFwfozXmkF149pq6a2iEqSUrxFICsUTV3XyB2GzRxVTeZctEIiKiPvP9B/dlvQQiIiIi6jM/2zmeur2QeC/ugWeOp+5z5xOH27ImIiLK3qJaJorIO0Rku4j4IrIpsX2jiMyJyNbw68uJ6y4QkUdFZJeIfFHCyacislxEfiIiT4b/XbaYtbXaoKXjuauGcOPWA/B9hYITVYhVtkxsMBAz9LI/wkCpQmzArB8OrR3NYePKoTrHDgOxlKqsKJg6OlMEgJqBWCskw8G0lolxIOb4VddVOjQZDC9ly0QiIqL+8v7vPJz1EoiIiIioD/z6x2+re/34dB7PHJ2Nv79h64F2L4mIiLrMYmeIbQPwNgA/S7nuKaXU+eHXnyW2fwnAnwA4M/x6Q7j9cgC3KaXOBHBb+H3XEBFc9poz8fjBKfxo28HEDDGtLBBLa1OYxjbSK8QGLR1aSjVV0rV/8mL879efVfN6q84MsWh9x8JAbEkbA7FkVVhqy8SwKix6LOs5NJkHAKxhIEZERNQ3Gp0jSkREREQ0nwMT+brXX/jZtLcviYjoZLKoQEwptUMp9USj+4vIOgCjSqlfqOAdkKsBvCW8+mIAV4WXr0ps7xpv/uVTcMbqYXz+1p1x60SrKhBb+Ayx2aKHwXnaJQLASM5Erk4Vma4JRNLDuSiYOjodVFy1MxBLnj+1ZaJZapk4n1IgxpaJRER08hGRU0XkDhF5LKzOvyzc3tUV9vO5+t6Fz3YgIiIiImoHQWPv7RERUe9ZbIVYPaeLyEMi8lMReUW4bT2A5KCIfeE2AFijlBoLLx8EsPghVi2ma4K/vPBMPHl4On4DxzY0WEZihlijLRN1DcWKyqggEKvfLrERIgJL11LbN5ph68K4ZWKufWPkklVhRspammuZyAoxIiI6qbkA/lopdTaAlwB4r4icjS6vsJ/PP964PeslEBERERGVaaSTERER9aZ50xARuRXA2pSrPqiUuqHGzcYAnKaUOioiFwD4vyJyTqOLUkopEanZQ0dELgVwKQCcdtppjR62Jd503jpcd8azuHvXEQCAbVbMEEtpU5jGSmmZOFNwWxKIRcdPW0upQqz9LRPnrRBrqmViAYOWjmG7fQEeERFRtwo/NDQWXp4SkR0IPlR0MYBXhbtdBeBOAH+bwRKJiIiIiFou73Q+nLptx+GOn5OIiDpj3vRGKXWhUurclK9aYRiUUgWl1NHw8gMAngLwfAD7AWxI7Loh3AYAh8KWilFrxZp/fZRSVyilNimlNq1atWq+u9BSIoKPv+08DIXB1UJniNVqmTjUosDHNtIrxOJAbCZomTjazkBMSwRiqTPEmmuZuGY0BxGWrRMR0clNRDYC+FUAm9EDFfa1/OMN27JeAhERERF1ubf9+89rXjc+VWjLOXcfmWnLcYmIKHttaZkoIqtERA8vPxfAmQB2h2/Yh+NtjwAAIABJREFUTIrISyRINn4fQBSs3QjgkvDyJYntXefU5YP4yMXn4ozVwxjNmQubIaanVIgVW1ch9sLTluGc9UuqtsctE6ejlontC8TKWiZqKS0TG5whtv/EHH6x+xg2LBto7QKJiIh6jIgMA/gegL9USk0mrwvns6ZW2IvIpSKyRUS2jI+Pd2Cl87uK88OIiIiICMBk3kHwUrbaY2OTqdsB4A++fl+7lkRERH1qUeVIIvJWAP8GYBWAm0Rkq1Lq9QBeCeAjIuIA8AH8mVLqWHizvwDwDQADAH4UfgHAJwB8R0TeA+AZAL+zmLW1229fsAG/fUFQ7GYtsGXi7Kxbtm224GHNSGtmZF3x+5tSt0ch1fHZIgZMveH1LkTDLRNTyt9/vusI/vjqLXjDOWuxdd8JFFwPf3fRL7VtrURERN1OREwEYdg1Sqnvh5sPicg6pdRYvQp7pdQVAK4AgE2bNtVsS90pOw9NZb0EIiIiIuoCT41P4zWf+Sn+5a3n4fde3NxYlLGJfJtWRURE/WpRgZhS6noA16ds/x6CN2zSbrMFwLkp248CeM1i1pMV0yiFPWZKJVQay9CqKqNmndZViNUShVS+au/8sOBciQqxJlsm/uDRMbi+ws3bD8L1Fb75nhfjl9aNtm+xREREXSysrL8SwA6l1GcTV0UV9p9Al1fYJ73ucz/LeglERERE1AWeOjwNAPj2/Xvx5l9Z19ZORkRERO0rDzqJRCGToQm0lEqoNKkzxAoeBu32BmLJSq3RgdbMK6t5rrIKsZSWiVGFWEogds+uI3jlmSvxi797DW7/X6/Ci05f3r6FEhERdb+XAXg3gFeLyNbw6yIEQdhrReRJABeG3xMRERER9ZSH903g1Z/+aUP73rPrCHw/86YHRETUJGksOmmr9iYiJ4moZWKyReB87BozxIas9v5IdE0gAqgOVIglw7fUCrF4hlh5y8Rnj83imaOz+INf34iRnIkRfjqIiIhOckqpuwHUeunYUxX2Ht+8ICIiIqIUR6YLDe33rq9uxofefDZfVxIRUdNYIdYCZhyINR5x2mZ5IOb5CnnHx2CbAzERids6trsMfb4ZYrl4hlh5MHjPriMAgJefsbKNqyMiIqIsPO/vfpj1EoiIiIiojR7ZdwJv/MJdmC268+4rCywX2LZ/AnMpM+mJiKh7dUGBGAOxVoiCMMto/OG09PKWidGLhKE2t0wEStVa7a4Q0zWBJlFVWr0KsfJA7K5dR7Bm1MYZq4fbuj4iIiLqLLa2ISIiIup/H71pB3aMTeKRfRPz7vvX39m6oHMcmy0CfGlJRERNYiDWAqbRfMtEyyivEJsrBp9qGbA6EIiF1VqjbQ7EgGCOmF5jrlrUajLZMtH3FX6+6whedsbKBX9KiIiIiLrTFXftznoJRERERJSh2aKLsYm5+PvJ/PxVZGmUQtkHzYmIqPt1w+cYGIi1wEJmiFUGYjNhINbuGWJAaZ2dCMRMTWDWCMQ0TWDpWlmF2N5jszg+6+DFpy9v+9qIiIiosx7aezzrJRARERFRh6iUdz5/94pf4KUfv72h29frLvDTneMLXRYREWVktph9q1sGYi2wkBlilq7D9VX8x32mEHwiZrATFWLhOkdzHQjfjNoVYgBgG1rZDLGp8JNBy4fstq+NiIiIOuvm7YeyXgIRERERZejhBtooRq65b28bV0JERCcjBmItEM3KsozGw6xo3lhU3h2lo0N2+0MqQwvO3e4ZYtG56lXO2aZW1jJxJpql1oFgkIiIiIiIiIiIusf/+9XN8eXHDjQenhERETWCgViLmLoGq5kKsTAQi6qjoiCoExViUSVbR1om6hJXpKWxDb2sZWInZ6kRERFR5/zgkQNZL4GIiIiIOqDyXaAnDk7h/j3HyrbNFl1c8rX7qm57964j2Ht0FnNFD9+679k2rpKIiE5G7S9HOklYev1KqKr9o0DM8wCYmC10sEJM72CFmC7w/fotE/NOSoVYBx4HIiIi6pz3XftQ1ksgIiIiog5SCMaEvP7zPwMA7PnEm+Lr/v76bTXngL3yX+/gbHkiImoLVoi1iGk0F4jZ4b5FN2qZGARBA2YHZohp0QyxTlSIaXUrxCxDK6sQi1pHduJxICIios5IfviFiIiIqBVE5FQRuUNEHhOR7SJyWbj9wyKyX0S2hl8XJW7zARHZJSJPiMjrs1s9PXNstu71m58+Vvd6IiKihWAZTouYusA0mq8QKwVinasQi4K7JYMdCMQ0DYBf83rbLG+ZOFtghRgREVG/uXn7wayXQERERP3HBfDXSqkHRWQEwAMi8pPwus8ppT6d3FlEzgbwTgDnADgFwK0i8nylFD+5s0BKKdzy2CF4vsJF561r+rZERESdxgqxFlnoDLGi1/kZYlHFVqdaJgahWDrb0FBIfGp8NrzciceBiIiIOuOy67ZmvQQiIiLqM0qpMaXUg+HlKQA7AKyvc5OLAVynlCoopZ4GsAvAi9q/0v519b3P4E+/+QD+4poHy7ZLA2+PMQ4jIqIsMBBrEavJlolWZcvEggddE9hNVJktlKlp0DXBUEfCt+BctdiVLRMLHjRBRx4HIiIiIiIiIup9IrIRwK8C2Bxuep+IPCIiXxORZeG29QCeTdxsH+oHaDSP+/bM09awTur10N4TrV0MERFRA5g6tMjfvP4F+ONXnN7w/lGF2L1PHYXj+Zgpuhi0dEgjH6NZJNMQjOaMjpzL0gVmnco529CrZogNWp1ZGxEREbXf9Q/ty3oJRERE1MdEZBjA9wD8pVJqEsCXADwPwPkAxgB8ZgHHvFREtojIlvHx8Zaut5dNF1x8/Ec74g93ex7rvIiIqLdwUFOLvOHctU3t/4J1Izhj9TA+/qPHcfW9z2DI1jvWJtDQNIx2oF0iELSS9PzaL5BsU0PBTbRMDINBIiIi6n17jszgr779cNbLICIioj4lIiaCMOwapdT3AUApdShx/VcA/CD8dj+AUxM33xBuq6KUugLAFQCwadMmpj6hz/9kJ75699M4bfkgXvOCNfhxA3Nik+8J5R2OayMiomwxEMvI6pEcbvnLV+L2xw/jirt2476nj+GsNSMdOfepywfqVm210qWvfC7cOp8YCmaIVVaIMRAjIiLqB3/0jfuzXgIRERH1KQlay1wJYIdS6rOJ7euUUmPht28FsC28fCOAa0XkswBOAXAmgPs6uOSeV/SC928c18fTR2bKrntw73FM5V38xvNX4Re7g1aKv/fVzWX7fOVnuzuzUCIiohoYiGVI0wQXnr0GF569Bo/um4BpdCak+shvndux4aWvOmt13eurWya6GLT4tCQiIuoHuyveKCEiIiJqoZcBeDeAR0Vka7jt7wD8roicj2CC1R4AfwoASqntIvIdAI8BcAG8VynFkqUmRO9apb2n9LZ//zkA4PF/fkPN23/mJztbvygiIuopt2w/iNed01y3vVZi8tAlztuwpGPn0rTumc9lG5UtE1khRkRERERERET1KaXuRimjSfphndt8DMDH2raoPpec965qfNT6Bf/w404th4iIelCd6UodoWV7ejrZBTPEShViM0UPgzZzWiIiol6nFMdtEBEREfUjvswjIqJexUCMMmUbOoquH79pNltwMWiyQoyIiKjXve5zP8t6CURERETUBir+HyIiot7CQIwyZRvBUzCqEpstehi0GYgRERH1uicPT2e9BCIiIiJqoahjIjsBEBHRQk3mnUzPz0CMMlUdiLmcIUZERNTjfrxtLOslEBEREVEL7DkyE1+WcGTbiVmHBWJERLQgfsZDxBYViInIO0Rku4j4IrIpsf1dIrI18eWLyPnhdXeKyBOJ61aH220R+baI7BKRzSKycTFro95gh+0RC64HIKgQG7I4Q4yIiKiX/dl/Ppj1EoiIiIhoke56chyv+vSd+Pb9e+H7Kq4Q+//u2IUj04VsF0dERD0p6w9ULLZCbBuAtwEoGxKhlLpGKXW+Uup8AO8G8LRSamtil3dF1yulDofb3gPguFLqDACfA/DJRa6NekAuqhBzfHi+QsH1McAKMSIiop6VdfsDIiIiIlq8XYen8e4r7wMA/O33HsVHb9oR1ocFLrtua/oNiYiI6rh2895Mz7+oQEwptUMp9cQ8u/0ugOsaONzFAK4KL38XwGtEROrsT32gVCHmY7boAgArxIiIiHrYL3/4lqyXQERERESL9Omby9/uu+7+veC7dEREtFgHTsxlev5OzBD7HwC+VbHt62G7xH9IhF7rATwLAEopF8AEgBUdWB9lqDRDzMNsMWibOGizQoyIiKgX3fjwgayXQEREREQtoCqaWvlKIeOxL0RE1AeyroGatxRHRG4FsDblqg8qpW6Y57YvBjCrlNqW2PwupdR+ERkB8D0ELRWvbmLNEJFLAVwKAKeddlozN6UuUwrE/FIgxpaJREREPeXAiTn8+iduz3oZRERERLQI37x3D3668wi+esmmquvyjo8r736684siIqK+omVcbTxvIKaUunARx38nKqrDlFL7w/9Oici1AF6EIBDbD+BUAPtExACwBMDRGmu6AsAVALBp0yZ+PqWH2UYQfuUdDzOFoGXiIFsmEhER9ZR/+u/tWS+BiIiIiBbpH24ovaZTfLeNiIjaQMu4QqxtLRNFRAPwO0jMDxMRQ0RWhpdNAG8GEFWP3QjgkvDy2wHcrhT//PY72yxViM05rBAjIiLqRXuOzGa9BCIiIiJqkTseP5z1EoiIqE9lPY9yUYGYiLxVRPYBeCmAm0Tk5sTVrwTwrFJqd2KbDeBmEXkEwFYEVWFfCa+7EsAKEdkF4P0ALl/M2qg3xC0THZ8VYkRERD1Ky7rnARERERE15Yat+/G6z/0U0WfRk59J/8Nv3I9bHjuU1dKIiKiPjU3kMz3/opIHpdT1AK6vcd2dAF5SsW0GwAU19s8DeMdi1kO9J2qZWHC9+MUXK8SIiIh6C4v6iYiIiBo3PlWAUgqrR3OZreGy67aWff/JHz+R0UqIiIg6h6U4lKm4Qsz14XjBm2lDrBAjIiLqKZ7PQIyIiIioUZd+cwuGbQPffM+Ls14K/uKaB/GbZ63Gl3/6VNZLISIiajsmD5Sp5AyxaGLrACvEiIiIegrjMCIiIqLGPbT3RMfOdc3mZ3DKkgH85gtWAwAm5hx87e6n4+t/tO0gfrTtYMfWQ0RElCUGYpSpuGWi48ENP10+ZDMQIyIi6iU+WyYSERERdaUPXr8NALDnE28CAHzspsfwnS37slwSERFRZhiIUaaSLRMLrg8AyBkMxIiIiIiIiIiIWuXMD/4QFzxnGVaPZDe3jIiIKGta1gugk1syEJstuBi0dGiaZLwqIiIiagYLxIiIiIi6m+Mp/GL3MTx5eDrrpRAREWWGFWKUKRGBZWgouB5mHQ+DnB9GRETUc9gykYiIiKi73PHEYSwbtKq27xibzGA1RERE3YGBGGXONjQUnKhCjE9JIiIiIiIiIqKFmCt6+KUP/TjrZRAREXUltkykzNmGHrRMLLJCjIiIqBexQIyIiIiocX/yitNhtGFcxGd/shMXffGulh+XiIioXzAQo8zZUctEBmJEREQ9SYGJGBEREVGjTL01b8cppXDFz57C4ak8JvMOvnjbk3j6yExLjk1ERNSP2J+OMmebWlghxpaJREREvejQZCHrJRARERH1DF0TuL6CUgoiC68U235gEv/yw8fxLz98vIWrIyIi6l+sEKPM2YYezBBjhRgREVHTROQNIvKEiOwSkcuzWEPR9bM4LREREVHTuuG107/dvgsA8NT49IJuf8+uI9h4+U1487/d3cplERER9T2W41Dm2DKRiIhoYUREB/B/ALwWwD4A94vIjUqpx7JdGREREVH36bbXThd+9mfY84k3zbtf3vFw95NH8MdXb+nAqoiIiPoXAzHK3NrRHG57/BCUAl5+5sqsl0NERNRLXgRgl1JqNwCIyHUALgbAQIyIiIioWle8drr1/b+BCz/7UwDAZdc9hDNXD+OuJ49g89PHOrkMIiKikw5bJlLm/vkt5+Idm06FArB+6UDWyyEiIuol6wE8m/h+X7itjIhcKiJbRGTL+Ph4xxZHRETU71579pqsl0DN6YrXTmesHo4v37D1AD59y06GYdRSQykdmN5+wYamjvH1P/i1tqzl1S9Y3bJjNSJntu/t7xGbtSZEzdrxkTdken7+q6XMrRqx8S9vPQ9/8/qzMGjxKUlERNRqSqkrAFwBAJs2bVKtPv69H3g1rrvvWawYtpAzg/+TKgDyrg/b0OB4PpQCTF2ghYPj866PnKEhH84fyxnB/1GdLrjQROB4PpYMmPE58q4PQdBq2fMVFABDC441W/RghecxNA2mnj6c3lcKnh+sQynA8X1YuhavJaIAzBRcDFkGCl75dUlFz4epa/F9Td6PyvPmHR8Dpg6RoO2Rpkl87uh+OZ6C6wf7AcCc40HXBI7rwzb1+P4CwGTexZClx4+X5ysMWDpcz4eha9A1gesrGJqg6PowdIHvK9imDiig4HrQNQ0KCqamQaT0OBqawFcKhycLWDViw1eAgsJU3sWKIQueX3oKJX8OedeHJoBAkHc8KACjOSN+rBzXh6+AAUvHTMHFsG1A1wQTcw5sUw8eR8eL70ve8WBoWnzZMjTkHR9KBddHj1/w+GiYK3owNIGua3BcH6ahYXLOwcphK37eTeVdaAKYhgZNSo/NbCH4mQzbOmaLHozw5+orFf88ZgouAEDXNdi6Bsf342NYhoaZggvb0GAZGoqegucFzwlD1+LHSSmg6HpwPIVBW8dc0YNtaPAVYBla/Fyx9OBnOlP0MGDqMA0NufAcADBoGci7weNTcIPHTJPg52YZwc//6HQRSwZMFF0fIzkD0wU3/lkpBP9GJXxcon+jIsE2UxcYmgZNANcPfvaGJhABdE1g6hqKrg/H85EzdZi6Bk8pTOdd5EwNrhc8RyxDgxHeF9dTsE0NSgU/50HLwPHZIpYOmnA9BVMP7r8K/x0VPT94fEwdvq/g+QqmoUEXgef7cDwFTQBPAZYusI3g38NIzkDB9TFTcGEZwc+x4Prx47NkwETB9eOfbdHz4XoKeddDztDjcxRcL3iswufsdN6FCOB4CqMDBiy99PMquj6WDprxczlnaJjKB8/xybwD29AwMedg0DIwkjPi3xe+r+B4PgYsHUXXjx+DAVNHwfUhgvjfrRP+G5pzfOTM4PkbtZtXCpgpuvF9FACaFvy+NXVB0VPx76bjs0UAwNIBCwoKx2ac8DmlQykF11cYsg34SsH3FXJm8O/V9VX8HBnNmXHL+4Ib/K7OO158Pjd8PgbPf4l/Zxjhc6fg+vG//eRzMmdosE0dBceDrmvwvOB3Rs7UMT5VwPIhE44XPBdypobpgochW4+fj0op6JrgyHQRVnh/R3MGHC/4dyESzLx0vdLvGBX+2yuGa9I1gSbBeqzw364ugjnHi5/TBcfDkG2g6Pk4ZekAfuPMVVW/96n3tfu1EwDs+cSbMJl3UHR9HJspYs+RGawYtnF4Mo9r79sLADjnlCWYK7rYfWQGw7aBozNFrBqxsWLIwrPHZsO/Px6eu2oIq0dsTBVcrB7JQZfgb++AZcDWNdimhiHLwMoRG6Ye/Fs8bfkgxqcKWDJoQgB4voJAYBrB3wCR4PeLr4LfVYOWAS08riYCXQRa4rWJUsHDFP1tibYlv6fsffodv9LU/o209CQi6iVMH6hrLB20sl4CERFRr9kP4NTE9xvCbR21bskA/uq1z+/0aYmIiIia1RWvnSKjueDDPyuHbTx/zUi8/Y3nrevI+U9dPtjQftEHngDANtIrdNKCL4ZhRETUbdgykYiIiKh33Q/gTBE5XUQsAO8EcGPGayIiIiLqVnztREREdBJjhRgRERFRj1JKuSLyPgA3A9ABfE0ptT3jZRERERF1Jb52IiIiOrkxECMiIiLqYUqpHwL4YdbrICIiIuoFfO1ERER08mLLRCIiIiIiIiIiIiIiIuprDMSIiIiIiIiIiIiIiIiorzEQIyIiIiIiIiIiIiIior7GQIyIiIiIiIiIiIiIiIj6GgMxIiIiIiIiIiIiIiIi6msMxIiIiIiIiIiIiIiIiKivMRAjIiIiIiIiIiIiIiKiviZKqazXsCgiMg7gmTYceiWAI204LpXj49wZfJw7g49zZ/Bx7oxWP87PUUqtauHxaIH42mnBeP96G+9fb+P96228fwvD105dgq+dFoz3r7fx/vU23r/exvu3MA29dur5QKxdRGSLUmpT1uvod3ycO4OPc2fwce4MPs6dwceZmtXvzxnev97G+9fbeP96G+8fUbp+f+7w/vU23r/exvvX23j/2ostE4mIiIiIiIiIiIiIiKivMRAjIiIiIiIiIiIiIiKivsZArLYrsl7ASYKPc2fwce4MPs6dwce5M/g4U7P6/TnD+9fbeP96G+9fb+P9I0rX788d3r/exvvX23j/ehvvXxtxhhgRERERERERERERERH1NVaIERERERERERERERERUV9jIJZCRN4gIk+IyC4RuTzr9fQTEdkjIo+KyFYR2RJuWy4iPxGRJ8P/Lst6nb1GRL4mIodFZFtiW+rjKoEvhs/vR0TkhdmtvLfUeJw/LCL7w+f0VhG5KHHdB8LH+QkReX02q+4tInKqiNwhIo+JyHYRuSzczudzC9V5nPl8pgXp1ddOzbwuqff7RkQuCfd/UkQuyfD+tOT1QK37IyIXhI/XrvC20gX3r+nfW7WeryJyuohsDrd/W0Sszt271v4N7MafYSv/9nTjz1BEciJyn4g8HN6/f6q3JhGxw+93hddvXOj9zvj+fUNEnk78/M4Pt/fU8zOxBl1EHhKRH4Tf98XPj7pLLz8XhK+deur3Wo371xd/d8Pz87VTD/8Mha+dev61k/Tq6yalFL8SXwB0AE8BeC4AC8DDAM7Oel398gVgD4CVFds+BeDy8PLlAD6Z9Tp77QvAKwG8EMC2+R5XABcB+BEAAfASAJuzXn+vfNV4nD8M4H+l7Ht2+PvDBnB6+HtFz/o+dPsXgHUAXhheHgGwM3ws+XzuzOPM5zO/mv7q5ddOzbwuqfX7BsByALvD/y4LLy/L6P4s+vVAvfsD4L5wXwlv+/+3d3chl1VlAMf/DzRO0WhWhMiMoIbQRYSFhZFEKI2ORVMwFwOBUkHQx0V0UYgQ3XTZFxQJlflRZmZF4k1ZI3RlhWU2YR9jBTVMDmRq3diHTxd7vTOH8757wzmz5+y9lv8fbN599j4vZz1rPaz1vO8+Z58DM4hvpXlrKF+Be4DDZf8W4AMbjm+UNXCuYzgQXxNjWPp0T9nfBfy09PWObQI+CNxS9g8D31o37onjuw04tMPzq8rPhXZ/FLgLuH8op2obP7f5bLXnAtZOVc1rPfF9kgbW3fKa1k4VjyHWTsvPryo/y+tXWTf5CbHt3gAcy8w/Zua/gbuBgxO3qXUHgdvL/u3AOydsS5Uy8yfAk0uH+/r1IHBHdh4Czo+ICzfT0rr19HOfg8DdmflsZv4JOEY3v2hAZp7IzF+U/X8CjwF7MZ9HNdDPfcxnDWmtdlp1vrkWeCAzn8zMfwAPANdtutEwWj2wYzzl3HmZ+VB2f73cwYZrtpHW4R3ztbyb8mrg3vL7G69JR1wDZzmGI649sxzDMg7/Kg93lS0H2rQ4rvcC15QYVor7LId1ykB8farKT4CI2Ae8DfhKeTyUU1WNn2alxVywdprpvGbttK1dVY2htdO2NlW19rZeO9VcN3lBbLu9wF8WHv+V4clGq0nghxHxcES8vxy7IDNPlP2/ARdM07Tm9PWrOT6+D5ePM98ap2/5aT+fofIR6tfSvYvGfD5LlvoZzGetrub8WKUu6Ytz7vGPFc/esr98fA5Wmbf6jr8ceCoz/7t0fBJnuAbOfgzPcO2Z7RiW28Y8Apyk+2fF4wNtOhVHOf80XQyznWuW48vMrfH7VBm/z0bE7nKsxvz8HPAx4LnyeCinqhs/zUbtuWDtdFoN81qfJtbdRdZOQIVjaO1Ude1Ubd3kBTFt2lWZ+TrgAPChiHjz4slyRXvoarnWYL+eVV8CXglcDpwAPj1tc9oQEXuA7wAfycxnFs+Zz+PZoZ/NZz3fPK/qktbiKZqbt1pfA1teezLzf5l5ObCP7p2tr5q4SaNaji8iXg3cRBfn6+lu5fPxCZu4toh4O3AyMx+eui3SzFk71a+ZdXeLtVO9Y2jtVGftVHvd5AWx7Y4DFy083leOaQSZebz8PAl8j26ye2LrFmfl58npWtiUvn41x0eUmU+UBe454Mucvo2c/bymiNhFV+x9IzO/Ww6bzyPbqZ/NZ62p2vxYsS7pi3Pu8Y8Vz/Gyv3x8UmvMW33H/053W5IXLB3fqJHWwNmO4Uhrz6zHECAznwIeBN440KZTcZTzL6GLYfZzzUJ815XbOWVmPgt8jfXHb+r8fBPwjoj4M91tea4GPk+D46fJVZ0L1k5VzWs7am3dtXaqfwzB2qk8rab8rLpu8oLYdj8HLouISyLiHLovertv4jY1ISJeHBHnbu0D+4GjdP17Y3najcD3p2lhc/r69T7ghuhcCTy98FFyrWiryCreRZfT0PXz4YjYHRGXAJfRfdmlBpR7CH8VeCwzP7NwynweUV8/m89aU5W10xp1Sd988wNgf0S8tNyuZH85NhejxFPOPRMRV5Y55AZmULOtMW/tmK/l3cMPAofK72+8Jh1xDZzlGI649sxyDCPiFRFxftl/EfBWuu/66GvT4rgeAo6UGFaK++xH1umJ77cL/3AMuu+JWBy/avIzM2/KzH2ZeTFd3x7JzHfTyPhpVqrNBWunuua1Pq2su2DtVFQ7htZO9dZO1ddNmem2tAHXA7+nu2/pzVO3p5UNuBT4Vdl+s9W3dPcM/THwB+BHwMumbmttG/BNuo9J/4fuvqrv6+tXIIAvlvz+NXDF1O2vZevW+ESkAAABN0lEQVTp5ztLPz5aJucLF55/c+nn3wEHpm5/DRtwFd3tDB4FHinb9ebzxvrZfHZba6uxdlq1Lhmab4D30n0B8DHgPRPGNEo90BcPcAXdH2yPA18AYgbxrTxv9eVryYmflbi/DezecHyjrYFzHMOB+JoYQ+A1wC9LHEeBTwy1CXhheXysnL903bgnju9IGb+jwNeBPTXm51KsbwHub2n83Oa11ZoLWDtVN6/1xNfEulte39qp4jHE2qmJ2okK66YoLyBJkiRJkiRJkiQ1yVsmSpIkSZIkSZIkqWleEJMkSZIkSZIkSVLTvCAmSZIkSZIkSZKkpnlBTJIkSZIkSZIkSU3zgpgkSZIkSZIkSZKa5gUxSZIkSZIkSZIkNc0LYpIkSZIkSZIkSWqaF8QkSZIkSZIkSZLUtP8Dk8hxFYQ7rC8AAAAASUVORK5CYII=\n",
      "text/plain": [
       "<Figure size 2160x360 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "agent.train(num_frames)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test\n",
    "Run the trained agent (1 episode)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "score:  -235.42615105825175\n"
     ]
    }
   ],
   "source": [
    "# test\n",
    "if IN_COLAB:\n",
    "    agent.env = gym.wrappers.Monitor(agent.env, \"videos\", force=True)\n",
    "frames = agent.test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Render"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Define the Animation class */\n",
       "  function Animation(frames, img_id, slider_id, interval, loop_select_id){\n",
       "    this.img_id = img_id;\n",
       "    this.slider_id = slider_id;\n",
       "    this.loop_select_id = loop_select_id;\n",
       "    this.interval = interval;\n",
       "    this.current_frame = 0;\n",
       "    this.direction = 0;\n",
       "    this.timer = null;\n",
       "    this.frames = new Array(frames.length);\n",
       "\n",
       "    for (var i=0; i<frames.length; i++)\n",
       "    {\n",
       "     this.frames[i] = new Image();\n",
       "     this.frames[i].src = frames[i];\n",
       "    }\n",
       "    document.getElementById(this.slider_id).max = this.frames.length - 1;\n",
       "    this.set_frame(this.current_frame);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.get_loop_state = function(){\n",
       "    var button_group = document[this.loop_select_id].state;\n",
       "    for (var i = 0; i < button_group.length; i++) {\n",
       "        var button = button_group[i];\n",
       "        if (button.checked) {\n",
       "            return button.value;\n",
       "        }\n",
       "    }\n",
       "    return undefined;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.set_frame = function(frame){\n",
       "    this.current_frame = frame;\n",
       "    document.getElementById(this.img_id).src = this.frames[this.current_frame].src;\n",
       "    document.getElementById(this.slider_id).value = this.current_frame;\n",
       "  }\n",
       "\n",
       "  Animation.prototype.next_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.min(this.frames.length - 1, this.current_frame + 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.previous_frame = function()\n",
       "  {\n",
       "    this.set_frame(Math.max(0, this.current_frame - 1));\n",
       "  }\n",
       "\n",
       "  Animation.prototype.first_frame = function()\n",
       "  {\n",
       "    this.set_frame(0);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.last_frame = function()\n",
       "  {\n",
       "    this.set_frame(this.frames.length - 1);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.slower = function()\n",
       "  {\n",
       "    this.interval /= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.faster = function()\n",
       "  {\n",
       "    this.interval *= 0.7;\n",
       "    if(this.direction > 0){this.play_animation();}\n",
       "    else if(this.direction < 0){this.reverse_animation();}\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_forward = function()\n",
       "  {\n",
       "    this.current_frame += 1;\n",
       "    if(this.current_frame < this.frames.length){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.first_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.last_frame();\n",
       "        this.reverse_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.last_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.anim_step_reverse = function()\n",
       "  {\n",
       "    this.current_frame -= 1;\n",
       "    if(this.current_frame >= 0){\n",
       "      this.set_frame(this.current_frame);\n",
       "    }else{\n",
       "      var loop_state = this.get_loop_state();\n",
       "      if(loop_state == \"loop\"){\n",
       "        this.last_frame();\n",
       "      }else if(loop_state == \"reflect\"){\n",
       "        this.first_frame();\n",
       "        this.play_animation();\n",
       "      }else{\n",
       "        this.pause_animation();\n",
       "        this.first_frame();\n",
       "      }\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.pause_animation = function()\n",
       "  {\n",
       "    this.direction = 0;\n",
       "    if (this.timer){\n",
       "      clearInterval(this.timer);\n",
       "      this.timer = null;\n",
       "    }\n",
       "  }\n",
       "\n",
       "  Animation.prototype.play_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = 1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_forward();}, this.interval);\n",
       "  }\n",
       "\n",
       "  Animation.prototype.reverse_animation = function()\n",
       "  {\n",
       "    this.pause_animation();\n",
       "    this.direction = -1;\n",
       "    var t = this;\n",
       "    if (!this.timer) this.timer = setInterval(function(){t.anim_step_reverse();}, this.interval);\n",
       "  }\n",
       "</script>\n",
       "\n",
       "<div class=\"animation\" align=\"center\">\n",
       "    <img id=\"_anim_imgHBPCUPCEFXYUQGAN\">\n",
       "    <br>\n",
       "    <input id=\"_anim_sliderHBPCUPCEFXYUQGAN\" type=\"range\" style=\"width:350px\" name=\"points\" min=\"0\" max=\"1\" step=\"1\" value=\"0\" onchange=\"animHBPCUPCEFXYUQGAN.set_frame(parseInt(this.value));\"></input>\n",
       "    <br>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.slower()\">&#8211;</button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.first_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.previous_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.reverse_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.pause_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.play_animation()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.next_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.last_frame()\"><img class=\"anim_icon\" src=\"\"></button>\n",
       "    <button onclick=\"animHBPCUPCEFXYUQGAN.faster()\">+</button>\n",
       "  <form action=\"#n\" name=\"_anim_loop_selectHBPCUPCEFXYUQGAN\" class=\"anim_control\">\n",
       "    <input type=\"radio\" name=\"state\" value=\"once\" > Once </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"loop\" checked> Loop </input>\n",
       "    <input type=\"radio\" name=\"state\" value=\"reflect\" > Reflect </input>\n",
       "  </form>\n",
       "</div>\n",
       "\n",
       "\n",
       "<script language=\"javascript\">\n",
       "  /* Instantiate the Animation class. */\n",
       "  /* The IDs given should match those used in the template above. */\n",
       "  (function() {\n",
       "    var img_id = \"_anim_imgHBPCUPCEFXYUQGAN\";\n",
       "    var slider_id = \"_anim_sliderHBPCUPCEFXYUQGAN\";\n",
       "    var loop_select_id = \"_anim_loop_selectHBPCUPCEFXYUQGAN\";\n",
       "    var frames = new Array(0);\n",
       "    \n",
       "  frames[0] = \"\"\n",
       "  frames[1] = \"\"\n",
       "  frames[2] = \"\"\n",
       "  frames[3] = \"\"\n",
       "  frames[4] = \"\"\n",
       "  frames[5] = \"\"\n",
       "  frames[6] = \"\"\n",
       "  frames[7] = \"\"\n",
       "  frames[8] = \"\"\n",
       "  frames[9] = \"\"\n",
       "  frames[10] = \"\"\n",
       "  frames[11] = \"\"\n",
       "  frames[12] = \"\"\n",
       "  frames[13] = \"\"\n",
       "  frames[14] = \"\"\n",
       "  frames[15] = \"\"\n",
       "  frames[16] = \"\"\n",
       "  frames[17] = \"\"\n",
       "  frames[18] = \"\"\n",
       "  frames[19] = \"\"\n",
       "  frames[20] = \"\"\n",
       "  frames[21] = \"\"\n",
       "  frames[22] = \"\"\n",
       "  frames[23] = \"\"\n",
       "  frames[24] = \"\"\n",
       "  frames[25] = \"\"\n",
       "  frames[26] = \"\"\n",
       "  frames[27] = \"\"\n",
       "  frames[28] = \"\"\n",
       "  frames[29] = \"\"\n",
       "  frames[30] = \"\"\n",
       "  frames[31] = \"\"\n",
       "  frames[32] = \"\"\n",
       "  frames[33] = \"\"\n",
       "  frames[34] = \"\"\n",
       "  frames[35] = \"\"\n",
       "  frames[36] = \"\"\n",
       "  frames[37] = \"\"\n",
       "  frames[38] = \"\"\n",
       "  frames[39] = \"\"\n",
       "  frames[40] = \"\"\n",
       "  frames[41] = \"\"\n",
       "  frames[42] = \"\"\n",
       "  frames[43] = \"\"\n",
       "  frames[44] = \"\"\n",
       "  frames[45] = \"\"\n",
       "  frames[46] = \"\"\n",
       "  frames[47] = \"\"\n",
       "  frames[48] = \"\"\n",
       "  frames[49] = \"\"\n",
       "  frames[50] = \"\"\n",
       "  frames[51] = \"\"\n",
       "  frames[52] = \"\"\n",
       "  frames[53] = \"\"\n",
       "  frames[54] = \"\"\n",
       "  frames[55] = \"\"\n",
       "  frames[56] = \"\"\n",
       "  frames[57] = \"\"\n",
       "  frames[58] = \"\"\n",
       "  frames[59] = \"\"\n",
       "  frames[60] = \"\"\n",
       "  frames[61] = \"\"\n",
       "  frames[62] = \"\"\n",
       "  frames[63] = \"\"\n",
       "  frames[64] = \"\"\n",
       "  frames[65] = \"\"\n",
       "  frames[66] = \"\"\n",
       "  frames[67] = \"\"\n",
       "  frames[68] = \"\"\n",
       "  frames[69] = \"\"\n",
       "  frames[70] = \"\"\n",
       "  frames[71] = \"\"\n",
       "  frames[72] = \"\"\n",
       "  frames[73] = \"\"\n",
       "  frames[74] = \"\"\n",
       "  frames[75] = \"\"\n",
       "  frames[76] = \"\"\n",
       "  frames[77] = \"\"\n",
       "  frames[78] = \"\"\n",
       "  frames[79] = \"\"\n",
       "  frames[80] = \"\"\n",
       "  frames[81] = \"\"\n",
       "  frames[82] = \"\"\n",
       "  frames[83] = \"\"\n",
       "  frames[84] = \"\"\n",
       "  frames[85] = \"\"\n",
       "  frames[86] = \"\"\n",
       "  frames[87] = \"\"\n",
       "  frames[88] = \"\"\n",
       "  frames[89] = \"\"\n",
       "  frames[90] = \"\"\n",
       "  frames[91] = \"\"\n",
       "  frames[92] = \"\"\n",
       "  frames[93] = \"\"\n",
       "  frames[94] = \"\"\n",
       "  frames[95] = \"\"\n",
       "  frames[96] = \"\"\n",
       "  frames[97] = \"\"\n",
       "  frames[98] = \"\"\n",
       "  frames[99] = \"\"\n",
       "  frames[100] = \"\"\n",
       "  frames[101] = \"\"\n",
       "  frames[102] = \"\"\n",
       "  frames[103] = \"\"\n",
       "  frames[104] = \"\"\n",
       "  frames[105] = \"\"\n",
       "  frames[106] = \"\"\n",
       "  frames[107] = \"\"\n",
       "  frames[108] = \"\"\n",
       "  frames[109] = \"\"\n",
       "  frames[110] = \"\"\n",
       "  frames[111] = \"\"\n",
       "  frames[112] = \"\"\n",
       "  frames[113] = \"\"\n",
       "  frames[114] = \"\"\n",
       "  frames[115] = \"\"\n",
       "  frames[116] = \"\"\n",
       "  frames[117] = \"\"\n",
       "  frames[118] = \"\"\n",
       "  frames[119] = \"\"\n",
       "  frames[120] = \"\"\n",
       "  frames[121] = \"\"\n",
       "  frames[122] = \"\"\n",
       "  frames[123] = \"\"\n",
       "  frames[124] = \"\"\n",
       "  frames[125] = \"\"\n",
       "  frames[126] = \"\"\n",
       "  frames[127] = \"\"\n",
       "  frames[128] = \"\"\n",
       "  frames[129] = \"\"\n",
       "  frames[130] = \"\"\n",
       "  frames[131] = \"\"\n",
       "  frames[132] = \"\"\n",
       "  frames[133] = \"\"\n",
       "  frames[134] = \"\"\n",
       "  frames[135] = \"\"\n",
       "  frames[136] = \"\"\n",
       "  frames[137] = \"\"\n",
       "  frames[138] = \"\"\n",
       "  frames[139] = \"\"\n",
       "  frames[140] = \"\"\n",
       "  frames[141] = \"\"\n",
       "  frames[142] = \"\"\n",
       "  frames[143] = \"\"\n",
       "  frames[144] = \"\"\n",
       "  frames[145] = \"\"\n",
       "  frames[146] = \"\"\n",
       "  frames[147] = \"\"\n",
       "  frames[148] = \"\"\n",
       "  frames[149] = \"\"\n",
       "  frames[150] = \"\"\n",
       "  frames[151] = \"\"\n",
       "  frames[152] = \"\"\n",
       "  frames[153] = \"\"\n",
       "  frames[154] = \"\"\n",
       "  frames[155] = \"\"\n",
       "  frames[156] = \"\"\n",
       "  frames[157] = \"\"\n",
       "  frames[158] = \"\"\n",
       "  frames[159] = \"\"\n",
       "  frames[160] = \"\"\n",
       "  frames[161] = \"\"\n",
       "  frames[162] = \"\"\n",
       "  frames[163] = \"\"\n",
       "  frames[164] = \"\"\n",
       "  frames[165] = \"\"\n",
       "  frames[166] = \"\"\n",
       "  frames[167] = \"\"\n",
       "  frames[168] = \"\"\n",
       "  frames[169] = \"\"\n",
       "  frames[170] = \"\"\n",
       "  frames[171] = \"\"\n",
       "  frames[172] = \"\"\n",
       "  frames[173] = \"\"\n",
       "  frames[174] = \"\"\n",
       "  frames[175] = \"\"\n",
       "  frames[176] = \"\"\n",
       "  frames[177] = \"\"\n",
       "  frames[178] = \"\"\n",
       "  frames[179] = \"\"\n",
       "  frames[180] = \"\"\n",
       "  frames[181] = \"\"\n",
       "  frames[182] = \"\"\n",
       "  frames[183] = \"\"\n",
       "  frames[184] = \"\"\n",
       "  frames[185] = \"\"\n",
       "  frames[186] = \"\"\n",
       "  frames[187] = \"\"\n",
       "  frames[188] = \"\"\n",
       "  frames[189] = \"\"\n",
       "  frames[190] = \"\"\n",
       "  frames[191] = \"\"\n",
       "  frames[192] = \"\"\n",
       "  frames[193] = \"\"\n",
       "  frames[194] = \"\"\n",
       "  frames[195] = \"\"\n",
       "  frames[196] = \"\"\n",
       "  frames[197] = \"\"\n",
       "  frames[198] = \"\"\n",
       "  frames[199] = \"\"\n",
       "\n",
       "\n",
       "    /* set a timeout to make sure all the above elements are created before\n",
       "       the object is initialized. */\n",
       "    setTimeout(function() {\n",
       "        animHBPCUPCEFXYUQGAN = new Animation(frames, img_id, slider_id, 50, loop_select_id);\n",
       "    }, 0);\n",
       "  })()\n",
       "</script>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "if IN_COLAB:  # for colab\n",
    "    import base64\n",
    "    import glob\n",
    "    import io\n",
    "    import os\n",
    "\n",
    "    from IPython.display import HTML, display\n",
    "\n",
    "    def ipython_show_video(path: str) -> None:\n",
    "        \"\"\"Show a video at `path` within IPython Notebook.\"\"\"\n",
    "        if not os.path.isfile(path):\n",
    "            raise NameError(\"Cannot access: {}\".format(path))\n",
    "\n",
    "        video = io.open(path, \"r+b\").read()\n",
    "        encoded = base64.b64encode(video)\n",
    "\n",
    "        display(HTML(\n",
    "            data=\"\"\"\n",
    "            <video alt=\"test\" controls>\n",
    "            <source src=\"data:video/mp4;base64,{0}\" type=\"video/mp4\"/>\n",
    "            </video>\n",
    "            \"\"\".format(encoded.decode(\"ascii\"))\n",
    "        ))\n",
    "\n",
    "    list_of_files = glob.glob(\"videos/*.mp4\")\n",
    "    latest_file = max(list_of_files, key=os.path.getctime)\n",
    "    print(latest_file)\n",
    "    ipython_show_video(latest_file)\n",
    "\n",
    "else:  # for jupyter\n",
    "    from matplotlib import animation\n",
    "    from JSAnimation.IPython_display import display_animation\n",
    "    from IPython.display import display\n",
    "\n",
    "\n",
    "    def display_frames_as_gif(frames):\n",
    "        \"\"\"Displays a list of frames as a gif, with controls.\"\"\"\n",
    "        patch = plt.imshow(frames[0])\n",
    "        plt.axis('off')\n",
    "\n",
    "        def animate(i):\n",
    "            patch.set_data(frames[i])\n",
    "\n",
    "        anim = animation.FuncAnimation(\n",
    "            plt.gcf(), animate, frames = len(frames), interval=50\n",
    "        )\n",
    "        display(display_animation(anim, default_mode='loop'))\n",
    "\n",
    "\n",
    "    # display \n",
    "    display_frames_as_gif(frames)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pg-is-all-you-need",
   "language": "python",
   "name": "pg-is-all-you-need"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
